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.api.batch; 021 022 import org.sonar.api.database.DatabaseSession; 023 import org.sonar.api.database.model.*; 024 import org.sonar.api.design.DependencyDto; 025 026 import java.util.List; 027 import javax.persistence.Query; 028 029 /** 030 * @since 1.10 031 */ 032 public abstract class AbstractPurge implements Purge { 033 034 private static final int MAX_IN_ELEMENTS = 950; 035 036 private int sqlInPageSize = MAX_IN_ELEMENTS; 037 private DatabaseSession session; 038 039 public AbstractPurge(DatabaseSession session) { 040 this.session = session; 041 } 042 043 protected DatabaseSession getSession() { 044 return session; 045 } 046 047 /** 048 * Delete SNAPSHOTS and all dependent tables (MEASURES, ...) 049 */ 050 protected void deleteSnapshotData(List<Integer> snapshotIds) { 051 deleteMeasuresBySnapshotId(snapshotIds); 052 deleteSources(snapshotIds); 053 deleteViolations(snapshotIds); 054 deleteDependencies(snapshotIds); 055 deleteSnapshots(snapshotIds); 056 } 057 058 protected void deleteDependencies(List<Integer> snapshotIds) { 059 executeQuery(snapshotIds, "delete from " + DependencyDto.class.getSimpleName() + " d where d.fromSnapshotId in (:ids)"); 060 executeQuery(snapshotIds, "delete from " + DependencyDto.class.getSimpleName() + " d where d.toSnapshotId in (:ids)"); 061 } 062 063 /** 064 * Delete all measures, including MEASURE_DATA 065 */ 066 protected void deleteMeasuresBySnapshotId(List<Integer> snapshotIds) { 067 executeQuery(snapshotIds, "delete from " + MeasureData.class.getSimpleName() + " m where m.snapshotId in (:ids)"); 068 executeQuery(snapshotIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.snapshotId in (:ids)"); 069 } 070 071 /** 072 * Delete all measures, including MEASURE_DATA 073 */ 074 protected void deleteMeasuresById(List<Integer> measureIds) { 075 executeQuery(measureIds, "delete from " + MeasureData.class.getSimpleName() + " m where m.measure.id in (:ids)"); 076 executeQuery(measureIds, "delete from " + MeasureModel.class.getSimpleName() + " m where m.id in (:ids)"); 077 } 078 079 /** 080 * Delete SNAPSHOT_SOURCES table 081 */ 082 protected void deleteSources(List<Integer> snapshotIds) { 083 executeQuery(snapshotIds, "delete from " + SnapshotSource.class.getSimpleName() + " e where e.snapshotId in (:ids)"); 084 } 085 086 /** 087 * Delete violations (RULE_FAILURES table) 088 */ 089 protected void deleteViolations(List<Integer> snapshotIds) { 090 executeQuery(snapshotIds, "delete from " + RuleFailureModel.class.getSimpleName() + " e where e.snapshotId in (:ids)"); 091 } 092 093 /** 094 * Delete SNAPSHOTS table 095 */ 096 protected void deleteSnapshots(List<Integer> snapshotIds) { 097 executeQuery(snapshotIds, "delete from " + Snapshot.class.getSimpleName() + " s where s.id in (:ids)"); 098 } 099 100 101 /** 102 * Paginate execution of SQL requests to avoid exceeding size of rollback segment 103 */ 104 protected void executeQuery(List<Integer> ids, String hql) { 105 if (ids == null || ids.isEmpty()) { 106 return; 107 } 108 109 int index = 0; 110 while (index < ids.size()) { 111 Query query = session.createQuery(hql); 112 List<Integer> paginedSids = ids.subList(index, Math.min(ids.size(), index + sqlInPageSize)); 113 query.setParameter("ids", paginedSids); 114 query.executeUpdate(); 115 index += sqlInPageSize; 116 session.commit(); 117 } 118 } 119 }