001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * Sonar is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * Sonar is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with Sonar; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 019 */ 020 package org.sonar.core.purge; 021 022 import org.sonar.api.batch.Purge; 023 import org.sonar.api.database.DatabaseSession; 024 import org.sonar.api.database.model.*; 025 import org.sonar.api.design.DependencyDto; 026 027 import javax.persistence.Query; 028 import java.util.List; 029 030 public abstract class AbstractPurge implements Purge { 031 032 private static final int MAX_IN_ELEMENTS = 950; 033 034 private int sqlInPageSize = MAX_IN_ELEMENTS; 035 private DatabaseSession session; 036 037 public AbstractPurge(DatabaseSession session) { 038 this.session = session; 039 } 040 041 protected DatabaseSession getSession() { 042 return session; 043 } 044 045 /** 046 * Delete SNAPSHOTS and all dependent tables (MEASURES, ...) 047 */ 048 protected void deleteSnapshotData(List<Integer> snapshotIds) { 049 deleteMeasuresBySnapshotId(snapshotIds); 050 deleteSources(snapshotIds); 051 deleteViolations(snapshotIds); 052 deleteDependencies(snapshotIds); 053 deleteSnapshots(snapshotIds); 054 } 055 056 protected void deleteDependencies(List<Integer> snapshotIds) { 057 executeQuery(snapshotIds, "delete from " + DependencyDto.class.getSimpleName() + " d where d.fromSnapshotId in (:ids)"); 058 executeQuery(snapshotIds, "delete from " + DependencyDto.class.getSimpleName() + " d where d.toSnapshotId in (:ids)"); 059 } 060 061 /** 062 * Delete all measures, including MEASURE_DATA 063 */ 064 protected void deleteMeasuresBySnapshotId(List<Integer> snapshotIds) { 065 executeQuery(snapshotIds, "delete from " + MeasureData.class.getSimpleName() + " m where m.snapshotId in (:ids)"); 066 executeQuery(snapshotIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.snapshotId in (:ids)"); 067 } 068 069 /** 070 * Delete all measures, including MEASURE_DATA 071 */ 072 protected void deleteMeasuresById(List<Integer> measureIds) { 073 executeQuery(measureIds, "delete from " + MeasureData.class.getSimpleName() + " m where m.measure.id in (:ids)"); 074 executeQuery(measureIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.id in (:ids)"); 075 } 076 077 /** 078 * Delete SNAPSHOT_SOURCES table 079 */ 080 protected void deleteSources(List<Integer> snapshotIds) { 081 executeQuery(snapshotIds, "delete from " + SnapshotSource.class.getSimpleName() + " e where e.snapshotId in (:ids)"); 082 } 083 084 /** 085 * Delete violations (RULE_FAILURES table) 086 */ 087 protected void deleteViolations(List<Integer> snapshotIds) { 088 executeQuery(snapshotIds, "delete from " + RuleFailureModel.class.getSimpleName() + " e where e.snapshotId in (:ids)"); 089 } 090 091 /** 092 * Delete SNAPSHOTS table 093 */ 094 protected void deleteSnapshots(List<Integer> snapshotIds) { 095 executeQuery(snapshotIds, "delete from " + Snapshot.class.getSimpleName() + " s where s.id in (:ids)"); 096 } 097 098 099 /** 100 * Paginate execution of SQL requests to avoid exceeding size of rollback segment 101 */ 102 protected void executeQuery(List<Integer> ids, String hql) { 103 if (ids == null || ids.isEmpty()) { 104 return; 105 } 106 107 int index = 0; 108 while (index < ids.size()) { 109 Query query = session.createQuery(hql); 110 List<Integer> paginedSids = ids.subList(index, Math.min(ids.size(), index + sqlInPageSize)); 111 query.setParameter("ids", paginedSids); 112 query.executeUpdate(); 113 index += sqlInPageSize; 114 session.commit(); 115 } 116 } 117 }