]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7137 Fix migration on MySQL 695/head
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 15 Dec 2015 08:50:07 +0000 (09:50 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 15 Dec 2015 11:18:19 +0000 (12:18 +0100)
Use another connection to select all duplicated components

sonar-db/src/main/java/org/sonar/db/MyBatis.java
sonar-db/src/main/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeys.java
sonar-db/src/main/java/org/sonar/db/version/v53/Component.java [new file with mode: 0644]
sonar-db/src/main/java/org/sonar/db/version/v53/Migration53Mapper.java [new file with mode: 0644]
sonar-db/src/main/resources/org/sonar/db/version/v53/Migration53Mapper.xml [new file with mode: 0644]
sonar-db/src/test/java/org/sonar/db/version/v52/RemoveDuplicatedComponentKeysTest.java

index 9011a073e62c7cd6595dcd1b69e28b1fa9427220..232b74dd35913cbd70f5789f489bbffdad47ef5a 100644 (file)
@@ -132,6 +132,7 @@ import org.sonar.db.version.SchemaMigrationDto;
 import org.sonar.db.version.SchemaMigrationMapper;
 import org.sonar.db.version.v45.Migration45Mapper;
 import org.sonar.db.version.v50.Migration50Mapper;
+import org.sonar.db.version.v53.Migration53Mapper;
 
 public class MyBatis {
 
@@ -235,7 +236,7 @@ public class MyBatis {
       MeasureMapper.class, MetricMapper.class, CustomMeasureMapper.class, QualityGateMapper.class, QualityGateConditionMapper.class, ComponentMapper.class, SnapshotMapper.class,
       ProjectQgateAssociationMapper.class, EventMapper.class,
       CeQueueMapper.class, CeActivityMapper.class, ComponentLinkMapper.class,
-      Migration45Mapper.class, Migration50Mapper.class
+      Migration45Mapper.class, Migration50Mapper.class, Migration53Mapper.class
     };
     confBuilder.loadMappers(mappers);
 
index 557c562fca034e88816b8862beba36448bbd4fb4..658a521edfc3dac4e0f38124541fe454614e1658 100644 (file)
@@ -29,9 +29,13 @@ 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.
@@ -44,9 +48,11 @@ import org.sonar.db.version.Upsert;
 public class RemoveDuplicatedComponentKeys extends BaseDataChange {
 
   private final AtomicLong counter = new AtomicLong(0L);
+  private final DbClient dbClient;
 
-  public RemoveDuplicatedComponentKeys(Database db) {
+  public RemoveDuplicatedComponentKeys(Database db, DbClient dbClient) {
     super(db);
+    this.dbClient = dbClient;
   }
 
   @Override
@@ -54,10 +60,13 @@ public class RemoveDuplicatedComponentKeys extends BaseDataChange {
     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(context, componentUpdate, issuesUpdate);
+      RemoveDuplicatedComponentHandler handler = new RemoveDuplicatedComponentHandler(mapper, componentUpdate, issuesUpdate);
       context.prepareSelect(
         "SELECT p.kee, COUNT(p.kee) FROM projects p " +
           "GROUP BY p.kee " +
@@ -70,40 +79,39 @@ public class RemoveDuplicatedComponentKeys extends BaseDataChange {
       progress.log();
     } finally {
       progress.stop();
+      dbClient.closeSession(readSession);
       componentUpdate.close();
       issuesUpdate.close();
     }
   }
 
   private class RemoveDuplicatedComponentHandler implements Select.RowHandler {
-    private final Context context;
+    private final Migration53Mapper mapper;
     private final Upsert componentUpdate;
     private final Upsert issuesUpdate;
 
     private boolean isEmpty = true;
 
-    public RemoveDuplicatedComponentHandler(Context context, Upsert componentUpdate, Upsert issuesUpdate) {
-      this.context = context;
+    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 {
-      List<Component> components = context
-        .prepareSelect("SELECT p.id, p.uuid, p.project_uuid, p.enabled FROM projects p WHERE p.kee=? ORDER BY id")
-        .setString(1, row.getString(1))
-        .list(ComponentRowReader.INSTANCE);
+      String componentKey = row.getString(1);
+      List<Component> 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.id)))) {
+      for (Component componentToRemove : FluentIterable.from(components).filter(Predicates.not(new MatchComponentId(refComponent.getId())))) {
         componentUpdate
-          .setLong(1, componentToRemove.id)
+          .setLong(1, componentToRemove.getId())
           .addBatch();
         issuesUpdate
-          .setString(1, refComponent.uuid)
-          .setString(2, refComponent.projectUuid)
-          .setString(3, componentToRemove.uuid)
+          .setString(1, refComponent.getUuid())
+          .setString(2, refComponent.getProjectUuid())
+          .setString(3, componentToRemove.getUuid())
           .addBatch();
         counter.getAndIncrement();
         isEmpty = false;
@@ -120,7 +128,7 @@ public class RemoveDuplicatedComponentKeys extends BaseDataChange {
 
     @Override
     public boolean apply(@Nonnull Component input) {
-      return input.enabled;
+      return input.isEnabled();
     }
   }
 
@@ -134,30 +142,8 @@ public class RemoveDuplicatedComponentKeys extends BaseDataChange {
 
     @Override
     public boolean apply(@Nonnull Component input) {
-      return input.id == this.id;
-    }
-  }
-
-  private enum ComponentRowReader implements Select.RowReader<Component> {
-    INSTANCE;
-
-    @Override
-    public Component read(Select.Row row) throws SQLException {
-      return new Component(row.getLong(1), row.getString(2), row.getString(3), row.getBoolean(4));
+      return input.getId() == this.id;
     }
   }
 
-  private static class Component {
-    private final long id;
-    private final String uuid;
-    private final String projectUuid;
-    private final boolean enabled;
-
-    public Component(long id, String uuid, String projectUuid, boolean enabled) {
-      this.id = id;
-      this.uuid = uuid;
-      this.projectUuid = projectUuid;
-      this.enabled = enabled;
-    }
-  }
 }
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v53/Component.java b/sonar-db/src/main/java/org/sonar/db/version/v53/Component.java
new file mode 100644 (file)
index 0000000..e33bd11
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.v53;
+
+public class Component {
+
+  private long id;
+  private String uuid;
+  private String projectUuid;
+  private boolean enabled;
+
+  public long getId() {
+    return id;
+  }
+
+  public Component setId(long id) {
+    this.id = id;
+    return this;
+  }
+
+  public String getUuid() {
+    return uuid;
+  }
+
+  public Component setUuid(String uuid) {
+    this.uuid = uuid;
+    return this;
+  }
+
+  public String getProjectUuid() {
+    return projectUuid;
+  }
+
+  public Component setProjectUuid(String projectUuid) {
+    this.projectUuid = projectUuid;
+    return this;
+  }
+
+  public boolean isEnabled() {
+    return enabled;
+  }
+
+  public Component setEnabled(boolean enabled) {
+    this.enabled = enabled;
+    return this;
+  }
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/version/v53/Migration53Mapper.java b/sonar-db/src/main/java/org/sonar/db/version/v53/Migration53Mapper.java
new file mode 100644 (file)
index 0000000..74a34e3
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.v53;
+
+import java.util.List;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Select;
+
+public interface Migration53Mapper {
+
+  /**
+   * Return components having the same given key
+   */
+  @Select("SELECT p.id AS \"id\", p.uuid AS \"uuid\", p.project_uuid AS \"projectUuid\", p.enabled AS \"enabled\" FROM projects p WHERE p.kee=#{key} ORDER BY id")
+  @Result(javaType = Component.class)
+  List<Component> selectComponentsByKey(@Param("key") String componentKey);
+
+}
diff --git a/sonar-db/src/main/resources/org/sonar/db/version/v53/Migration53Mapper.xml b/sonar-db/src/main/resources/org/sonar/db/version/v53/Migration53Mapper.xml
new file mode 100644 (file)
index 0000000..509d00f
--- /dev/null
@@ -0,0 +1,7 @@
+<?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.db.version.v53.Migration53Mapper">
+
+</mapper>
+
index 79d5b1511abab5136f55cc4dcca8fb9587ebdf9a..122f0e94dee9755ef13bd170e7c888eae74e4fa8 100644 (file)
@@ -39,7 +39,7 @@ public class RemoveDuplicatedComponentKeysTest {
     db.executeUpdateSql("truncate table projects");
     db.executeUpdateSql("truncate table issues");
 
-    migration = new RemoveDuplicatedComponentKeys(db.database());
+    migration = new RemoveDuplicatedComponentKeys(db.database(), db.getDbClient());
   }
 
   @Test