All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.sonar.db.version.v52.RemoveDuplicatedComponentKeys Maven / Gradle / Ivy

There is a newer version: 6.3.1
Show newest version
/*
 * SonarQube
 * Copyright (C) 2009-2016 SonarSource SA
 * mailto:contact AT sonarsource DOT com
 *
 * This program 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.
 *
 * This program 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 this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.sonar.db.version.v52;

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.Nonnull;
import org.sonar.core.util.ProgressLogger;
import org.sonar.db.Database;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.version.BaseDataChange;
import org.sonar.db.version.Select;
import org.sonar.db.version.Upsert;
import org.sonar.db.version.v53.Component;
import org.sonar.db.version.v53.Migration53Mapper;

/**
 * Remove all duplicated component that have the same keys.
 * For each duplicated component key :
 * 
    *
  • Only the enabled one or last one (with the latest id) is kept
  • *
  • When deleting a component, all its issues are linked to the remaining component
  • *
*/ public class RemoveDuplicatedComponentKeys extends BaseDataChange { private final AtomicLong counter = new AtomicLong(0L); private final DbClient dbClient; public RemoveDuplicatedComponentKeys(Database db, DbClient dbClient) { super(db); this.dbClient = dbClient; } @Override public void execute(final Context context) throws SQLException { Upsert componentUpdate = context.prepareUpsert("DELETE FROM projects WHERE id=?"); Upsert issuesUpdate = context.prepareUpsert("UPDATE issues SET component_uuid=?, project_uuid=? WHERE component_uuid=?"); DbSession readSession = dbClient.openSession(false); Migration53Mapper mapper = readSession.getMapper(Migration53Mapper.class); ProgressLogger progress = ProgressLogger.create(getClass(), counter); progress.start(); try { RemoveDuplicatedComponentHandler handler = new RemoveDuplicatedComponentHandler(mapper, componentUpdate, issuesUpdate); context.prepareSelect( "SELECT p.kee, COUNT(p.kee) FROM projects p " + "GROUP BY p.kee " + "HAVING COUNT(p.kee) > 1") .scroll(handler); if (!handler.isEmpty) { componentUpdate.execute().commit(); issuesUpdate.execute().commit(); } progress.log(); } finally { progress.stop(); dbClient.closeSession(readSession); componentUpdate.close(); issuesUpdate.close(); } } private class RemoveDuplicatedComponentHandler implements Select.RowHandler { private final Migration53Mapper mapper; private final Upsert componentUpdate; private final Upsert issuesUpdate; private boolean isEmpty = true; public RemoveDuplicatedComponentHandler(Migration53Mapper mapper, Upsert componentUpdate, Upsert issuesUpdate) { this.mapper = mapper; this.componentUpdate = componentUpdate; this.issuesUpdate = issuesUpdate; } @Override public void handle(Select.Row row) throws SQLException { String componentKey = row.getString(1); List components = mapper.selectComponentsByKey(componentKey); // We keep the enabled component or the last component of the list Component refComponent = FluentIterable.from(components).firstMatch(EnabledComponent.INSTANCE).or(components.get(components.size() - 1)); for (Component componentToRemove : FluentIterable.from(components).filter(Predicates.not(new MatchComponentId(refComponent.getId())))) { componentUpdate .setLong(1, componentToRemove.getId()) .addBatch(); issuesUpdate .setString(1, refComponent.getUuid()) .setString(2, refComponent.getProjectUuid()) .setString(3, componentToRemove.getUuid()) .addBatch(); counter.getAndIncrement(); isEmpty = false; } } public boolean isEmpty() { return isEmpty; } } private enum EnabledComponent implements Predicate { INSTANCE; @Override public boolean apply(@Nonnull Component input) { return input.isEnabled(); } } private static class MatchComponentId implements Predicate { private final long id; public MatchComponentId(long id) { this.id = id; } @Override public boolean apply(@Nonnull Component input) { return input.getId() == this.id; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy