* 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.tags/6.0-RC1
@@ -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); | |||
} |
@@ -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; | |||
} |
@@ -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); | |||
} |
@@ -19,10 +19,17 @@ | |||
*/ | |||
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(); |
@@ -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 | |||
)); | |||
} | |||
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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; | |||
}); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |