]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3321 Fix bug in file rename algorithm 1100/head
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 13 Jul 2016 08:41:04 +0000 (10:41 +0200)
committerJulien HENRY <julien.henry@sonarsource.com>
Wed, 13 Jul 2016 09:10:45 +0000 (11:10 +0200)
* Real technical bug causing the error was that matches
were not properly filtered so that a file that was already
matched could be matched again
* This also allowed to spot a functional bug: matches candidates were
processed in ascending score order. Means that lowest score got highest priority.

23 files changed:
server/sonar-server/src/main/java/org/sonar/server/computation/filemove/FileMoveDetectionStep.java
server/sonar-server/src/main/java/org/sonar/server/computation/filemove/MatchesByScore.java
server/sonar-server/src/main/java/org/sonar/server/computation/filemove/MutableMovedFilesRepositoryImpl.java
server/sonar-server/src/test/java/org/sonar/server/computation/filemove/FileMoveDetectionStepTest.java
server/sonar-server/src/test/java/org/sonar/server/computation/filemove/MatchesByScoreTest.java
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1235_add_component_uuid_to_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1236_populate_component_uuid_of_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1237_delete_orphan_duplications_index_rows_without_component.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1238_make_component_uuid_not_null_on_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1239_add_analysis_uuid_to_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1240_populate_analysis_uuid_of_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1241_delete_orphan_duplications_index_rows_without_analysis.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1242_make_analysis_uuid_not_null_on_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1235_add_component_uuid_and_analysis_uuid_to_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1236_populate_component_uuid_and_analysis_uuid_of_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1237_delete_orphan_duplications_index_rows_without_component_or_analysis.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1238_make_component_uuid_and_analysis_uuid_not_null_on_duplications_index.rb [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java [new file with mode: 0644]
server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java [new file with mode: 0644]

index 9780878cecf45b21b09bb1050d6cdd1314cc362a..11c509acf94536adc658725ad4cef557373b6f13 100644 (file)
@@ -150,7 +150,8 @@ public class FileMoveDetectionStep implements ComputationStep {
 
   private Map<String, DbComponent> getDbFilesByKey() {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      // FIXME no need to use such a complex query, joining on SNAPSHOTS and retrieving all column of table PROJECTS, replace with dedicated mapper method
+      // FIXME no need to use such a complex query, joining on SNAPSHOTS and retrieving all column of table PROJECTS, replace with dedicated
+      // mapper method
       return from(dbClient.componentDao().selectDescendants(
         dbSession,
         ComponentTreeQuery.builder()
@@ -251,15 +252,15 @@ public class FileMoveDetectionStep implements ComputationStep {
       }
 
       List<Match> matchesToValidate = electedMatches.filter(matches);
-      if (matches.isEmpty()) {
+      if (matchesToValidate.isEmpty()) {
         continue;
       }
-      if (matches.size() == 1) {
+      if (matchesToValidate.size() == 1) {
         Match match = matches.get(0);
         electedMatches.add(match);
       } else {
         matchesPerFileForScore.clear();
-        for (Match match : matches) {
+        for (Match match : matchesToValidate) {
           matchesPerFileForScore.put(match.getDbKey(), match);
           matchesPerFileForScore.put(match.getReportKey(), match);
         }
index 69cde753d2a9ce03021b65f6dae53ad617865e1e..3de15f135c1c7e92677d7d903387ca2b8d71c251 100644 (file)
@@ -60,7 +60,8 @@ abstract class MatchesByScore implements Iterable<List<Match>> {
         return;
       }
 
-      int index = score - MIN_REQUIRED_SCORE;
+      // Store higher score first so that iterator get higher score first
+      int index = scoreMatrix.getMaxScore() - score;
       if (matches[index] == null) {
         matches[index] = new ArrayList<>(1);
       }
@@ -69,7 +70,6 @@ abstract class MatchesByScore implements Iterable<List<Match>> {
       totalMatches++;
     }
 
-
     private static boolean isAcceptableScore(int score) {
       return score >= MIN_REQUIRED_SCORE;
     }
index bb09fa17f305e6f9950d09f4e11e18acbd512516..03a659d86535d0bad89157244d2b41bdcfab84f6 100644 (file)
@@ -39,7 +39,7 @@ public class MutableMovedFilesRepositoryImpl implements MutableMovedFilesReposit
 
     OriginalFile existingOriginalFile = originalFiles.get(file.getKey());
     checkState(existingOriginalFile == null || existingOriginalFile.equals(originalFile),
-      "Original file %s already registered for file %s", existingOriginalFile, file);
+      "Original file %s already registered for file %s. Unable to register %s.", existingOriginalFile, file, originalFile);
     if (existingOriginalFile == null) {
       originalFiles.put(file.getKey(), originalFile);
     }
index 0cf21b266ae8c5e18de5c4bb11ff2a8f049d2036..71d8384422679c6c6f881fab2a00555831d62cf8 100644 (file)
  */
 package org.sonar.server.computation.filemove;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import org.apache.commons.io.FileUtils;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -80,6 +87,7 @@ public class FileMoveDetectionStepTest {
     "  }",
     "}"
   };
+
   private static final String[] LESS_CONTENT1 = {
     "package org.sonar.server.computation.filemove;",
     "",
@@ -310,7 +318,7 @@ public class FileMoveDetectionStepTest {
   public void execute_detects_move_if_content_of_file_is_same_in_DB_and_report() {
     analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
     ComponentDto[] dtos = mockComponents(FILE_1.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT1);
     setFilesInReport(FILE_2);
     setFileContentInReport(FILE_2_REF, CONTENT1);
 
@@ -327,7 +335,7 @@ public class FileMoveDetectionStepTest {
   public void execute_detects_no_move_if_content_of_file_is_not_similar_enough() {
     analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
     mockComponents(FILE_1.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT1);
     setFilesInReport(FILE_2);
     setFileContentInReport(FILE_2_REF, LESS_CONTENT1);
 
@@ -340,7 +348,7 @@ public class FileMoveDetectionStepTest {
   public void execute_detects_no_move_if_content_of_file_is_empty_in_DB() {
     analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
     mockComponents(FILE_1.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT_EMPTY);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT_EMPTY);
     setFilesInReport(FILE_2);
     setFileContentInReport(FILE_2_REF, CONTENT1);
 
@@ -353,7 +361,7 @@ public class FileMoveDetectionStepTest {
   public void execute_detects_no_move_if_content_of_file_is_empty_in_report() {
     analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
     mockComponents(FILE_1.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT1);
     setFilesInReport(FILE_2);
     setFileContentInReport(FILE_2_REF, CONTENT_EMPTY);
 
@@ -366,7 +374,7 @@ public class FileMoveDetectionStepTest {
   public void execute_detects_no_move_if_two_added_files_have_same_content_as_the_one_in_db() {
     analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
     mockComponents(FILE_1.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT1);
     setFilesInReport(FILE_2, FILE_3);
     setFileContentInReport(FILE_2_REF, CONTENT1);
     setFileContentInReport(FILE_3_REF, CONTENT1);
@@ -380,8 +388,8 @@ public class FileMoveDetectionStepTest {
   public void execute_detects_no_move_if_two_deleted_files_have_same_content_as_the_one_added() {
     analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
     mockComponents(FILE_1.getKey(), FILE_2.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT1);
-    mockContentOfFileIdDb(FILE_2.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_2.getKey(), CONTENT1);
     setFilesInReport(FILE_3);
     setFileContentInReport(FILE_3_REF, CONTENT1);
 
@@ -402,10 +410,10 @@ public class FileMoveDetectionStepTest {
     Component file5 = fileComponent(6);
     Component file6 = fileComponent(7);
     ComponentDto[] dtos = mockComponents(FILE_1.getKey(), FILE_2.getKey(), file4.getKey(), file5.getKey());
-    mockContentOfFileIdDb(FILE_1.getKey(), CONTENT1);
-    mockContentOfFileIdDb(FILE_2.getKey(), LESS_CONTENT1);
-    mockContentOfFileIdDb(file4.getKey(), new String[] {"e", "f", "g", "h", "i"});
-    mockContentOfFileIdDb(file5.getKey(), CONTENT2);
+    mockContentOfFileInDb(FILE_1.getKey(), CONTENT1);
+    mockContentOfFileInDb(FILE_2.getKey(), LESS_CONTENT1);
+    mockContentOfFileInDb(file4.getKey(), new String[] {"e", "f", "g", "h", "i"});
+    mockContentOfFileInDb(file5.getKey(), CONTENT2);
     setFilesInReport(FILE_3, file4, file6);
     setFileContentInReport(FILE_3_REF, CONTENT1);
     setFileContentInReport(file4.getReportAttributes().getRef(), new String[] {"a", "b"});
@@ -424,11 +432,60 @@ public class FileMoveDetectionStepTest {
     assertThat(originalFile5.getUuid()).isEqualTo(dtos[3].uuid());
   }
 
+  /**
+   * JH: A bug was encountered in the algorithm and I didn't manage to forge a simpler test case.
+   */
+  @Test
+  public void real_life_use_case() throws Exception {
+    analysisMetadataHolder.setBaseProjectSnapshot(SNAPSHOT);
+    List<String> componentDtoKey = new ArrayList<>();
+    for (File f : FileUtils.listFiles(new File("src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1"), null, false)) {
+      componentDtoKey.add(f.getName());
+      mockContentOfFileInDb(f.getName(), readLines(f));
+    }
+    mockComponents(componentDtoKey.toArray(new String[0]));
+
+    Map<String, Component> comps = new HashMap<>();
+    int i = 1;
+    for (File f : FileUtils.listFiles(new File("src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2"), null, false)) {
+      comps.put(f.getName(), builder(Component.Type.FILE, i)
+        .setKey(f.getName())
+        .setPath(f.getName())
+        .build());
+      setFileContentInReport(i++, readLines(f));
+    }
+
+    setFilesInReport(comps.values().toArray(new Component[0]));
+
+    underTest.execute();
+
+    Component makeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex = comps.get("MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java");
+    Component migrationRb1238 = comps.get("1238_make_component_uuid_and_analysis_uuid_not_null_on_duplications_index.rb");
+    Component addComponentUuidAndAnalysisUuidColumnToDuplicationsIndex = comps.get("AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java");
+    assertThat(movedFilesRepository.getComponentsWithOriginal()).containsOnly(
+      makeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex,
+      migrationRb1238,
+      addComponentUuidAndAnalysisUuidColumnToDuplicationsIndex);
+
+    assertThat(movedFilesRepository.getOriginalFile(makeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex).get().getKey())
+      .isEqualTo("MakeComponentUuidNotNullOnDuplicationsIndex.java");
+    assertThat(movedFilesRepository.getOriginalFile(migrationRb1238).get().getKey())
+      .isEqualTo("1242_make_analysis_uuid_not_null_on_duplications_index.rb");
+    assertThat(movedFilesRepository.getOriginalFile(addComponentUuidAndAnalysisUuidColumnToDuplicationsIndex).get().getKey())
+      .isEqualTo("AddComponentUuidColumnToDuplicationsIndex.java");
+  }
+
+  private String[] readLines(File filename) throws IOException {
+    return FileUtils
+      .readLines(filename, StandardCharsets.UTF_8)
+      .toArray(new String[0]);
+  }
+
   private void setFileContentInReport(int ref, String[] content) {
     sourceLinesRepository.addLines(ref, content);
   }
 
-  private void mockContentOfFileIdDb(String key, String[] content) {
+  private void mockContentOfFileInDb(String key, String[] content) {
     SourceLinesHashesComputer linesHashesComputer = new SourceLinesHashesComputer();
     SourceHashComputer sourceHashComputer = new SourceHashComputer();
     Iterator<String> lineIterator = Arrays.asList(content).iterator();
index 415bdb9718820feade37b172e76e5ad834348c99..06ade5734f024719e4522f93d8ffb8136d8bddb9 100644 (file)
@@ -66,14 +66,14 @@ public class MatchesByScoreTest {
 
     assertThat(matchesByScore.getSize()).isEqualTo(2);
     assertThat(Lists.newArrayList(matchesByScore)).isEqualTo(Arrays.asList(
-      ImmutableList.of(new Match("C", "1")), // 85
+      ImmutableList.of(new Match("A", "1")), // 92
       NO_MATCH,
       NO_MATCH,
       NO_MATCH,
       NO_MATCH,
       NO_MATCH,
       NO_MATCH,
-      ImmutableList.of(new Match("A", "1")) // 92
+      ImmutableList.of(new Match("C", "1")) // 85
     ));
   }
 
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1235_add_component_uuid_to_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1235_add_component_uuid_to_duplications_index.rb
new file mode 100644 (file)
index 0000000..47b75db
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class AddComponentUuidToDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.AddComponentUuidColumnToDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1236_populate_component_uuid_of_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1236_populate_component_uuid_of_duplications_index.rb
new file mode 100644 (file)
index 0000000..a893f08
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class PopulateComponentUuidOfDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.PopulateComponentUuidOfDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1237_delete_orphan_duplications_index_rows_without_component.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1237_delete_orphan_duplications_index_rows_without_component.rb
new file mode 100644 (file)
index 0000000..258b4ae
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class DeleteOrphanDuplicationsIndexRowsWithoutComponent < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.DeleteOrphanDuplicationsIndexRowsWithoutComponent')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1238_make_component_uuid_not_null_on_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1238_make_component_uuid_not_null_on_duplications_index.rb
new file mode 100644 (file)
index 0000000..861607d
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class MakeComponentUuidNotNullOnDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.MakeComponentUuidNotNullOnDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1239_add_analysis_uuid_to_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1239_add_analysis_uuid_to_duplications_index.rb
new file mode 100644 (file)
index 0000000..49a91b6
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class AddAnalysisUuidToDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.AddAnalysisUuidColumnToDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1240_populate_analysis_uuid_of_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1240_populate_analysis_uuid_of_duplications_index.rb
new file mode 100644 (file)
index 0000000..1021499
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class PopulateAnalysisUuidOfDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.PopulateAnalysisUuidOfDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1241_delete_orphan_duplications_index_rows_without_analysis.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1241_delete_orphan_duplications_index_rows_without_analysis.rb
new file mode 100644 (file)
index 0000000..1b37e46
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class DeleteOrphanDuplicationsIndexRowsWithoutAnalysis < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.DeleteOrphanDuplicationsIndexRowsWithoutAnalysis')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1242_make_analysis_uuid_not_null_on_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/1242_make_analysis_uuid_not_null_on_duplications_index.rb
new file mode 100644 (file)
index 0000000..e1e6787
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class MakeAnalysisUuidNotNullOnDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.MakeAnalysisUuidNotNullOnDuplicationsIndex')
+
+    add_index :duplications_index, [:analysis_uuid, :component_uuid], :name => 'duplication_analysis_component'
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/AddAnalysisUuidColumnToDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..04f86a0
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddAnalysisUuidColumnToDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_DUPLICATIONS_INDEX = "duplications_index";
+
+  public AddAnalysisUuidColumnToDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_DUPLICATIONS_INDEX)
+      .addColumn(newVarcharColumnDefBuilder().setColumnName("analysis_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+      .build());
+  }
+
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/AddComponentUuidColumnToDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..a25cf2c
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_PUBLICATIONS_INDEX = "duplications_index";
+
+  public AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_PUBLICATIONS_INDEX)
+      .addColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+      .addColumn(newVarcharColumnDefBuilder().setColumnName("analysis_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+      .build());
+  }
+
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/DeleteOrphanDuplicationsIndexRowsWithoutComponent.java
new file mode 100644 (file)
index 0000000..763dd89
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.BaseDataChange;
+import org.sonar.db.version.MassUpdate;
+
+public class DeleteOrphanDuplicationsIndexRowsWithoutComponent extends BaseDataChange {
+
+  public DeleteOrphanDuplicationsIndexRowsWithoutComponent(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    MassUpdate massUpdate = context.prepareMassUpdate();
+    massUpdate.select("SELECT id from duplications_index where component_uuid is null");
+    massUpdate.update("DELETE from duplications_index WHERE id=?");
+    massUpdate.rowPluralName("resources_index entries");
+    massUpdate.execute((row, update) -> {
+      update.setLong(1, row.getLong(1));
+      return true;
+    });
+  }
+
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v1/MakeComponentUuidNotNullOnDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..6233d86
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeComponentUuidNotNullOnDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_DUPLICATIONS_INDEX = "duplications_index";
+
+  public MakeComponentUuidNotNullOnDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AlterColumnsBuilder(getDatabase().getDialect(), TABLE_DUPLICATIONS_INDEX)
+      .updateColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+      .build());
+  }
+
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1235_add_component_uuid_and_analysis_uuid_to_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1235_add_component_uuid_and_analysis_uuid_to_duplications_index.rb
new file mode 100644 (file)
index 0000000..9a26364
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class AddComponentUuidAndAnalysisUuidToDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1236_populate_component_uuid_and_analysis_uuid_of_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1236_populate_component_uuid_and_analysis_uuid_of_duplications_index.rb
new file mode 100644 (file)
index 0000000..6303d5c
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class PopulateComponentUuidAndAnalysisUuidOfDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.PopulateComponentUuidAndAnalysisUuidOfDuplicationsIndex')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1237_delete_orphan_duplications_index_rows_without_component_or_analysis.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1237_delete_orphan_duplications_index_rows_without_component_or_analysis.rb
new file mode 100644 (file)
index 0000000..ebd45bd
--- /dev/null
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class DeleteOrphanDuplicationsIndexRowsWithoutComponentOrAnalysis < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.DeleteOrphanDuplicationsIndexRowsWithoutComponentOrAnalysis')
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1238_make_component_uuid_and_analysis_uuid_not_null_on_duplications_index.rb b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/1238_make_component_uuid_and_analysis_uuid_not_null_on_duplications_index.rb
new file mode 100644 (file)
index 0000000..11b957e
--- /dev/null
@@ -0,0 +1,31 @@
+#
+# 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.
+#
+
+#
+# SonarQube 6.0
+#
+class MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex < ActiveRecord::Migration
+
+  def self.up
+    execute_java_migration('org.sonar.db.version.v60.MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex')
+
+    add_index :duplications_index, [:analysis_uuid, :component_uuid], :name => 'duplication_analysis_component'
+  end
+end
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/AddComponentUuidAndAnalysisUuidColumnToDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..8e9280f
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AddColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class AddComponentUuidColumnToDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_PUBLICATIONS_INDEX = "duplications_index";
+
+  public AddComponentUuidColumnToDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDatabase().getDialect(), TABLE_PUBLICATIONS_INDEX)
+      .addColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(true).build())
+      .build());
+  }
+
+}
\ No newline at end of file
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java b/server/sonar-server/src/test/resources/org/sonar/server/computation/filemove/FileMoveDetectionStepTest/v2/MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex.java
new file mode 100644 (file)
index 0000000..e365b12
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.v60;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.db.version.AlterColumnsBuilder;
+import org.sonar.db.version.DdlChange;
+
+import static org.sonar.db.version.VarcharColumnDef.UUID_VARCHAR_SIZE;
+import static org.sonar.db.version.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+public class MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex extends DdlChange {
+
+  private static final String TABLE_DUPLICATIONS_INDEX = "duplications_index";
+
+  public MakeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AlterColumnsBuilder(getDatabase().getDialect(), TABLE_DUPLICATIONS_INDEX)
+      .updateColumn(newVarcharColumnDefBuilder().setColumnName("component_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+      .updateColumn(newVarcharColumnDefBuilder().setColumnName("analysis_uuid").setLimit(UUID_VARCHAR_SIZE).setIsNullable(false).build())
+      .build());
+  }
+
+}
\ No newline at end of file