import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.FileMoveRowDto;
-import org.sonar.db.source.LineHashesWithKeyDto;
+import org.sonar.db.source.LineHashesWithUuidDto;
import static com.google.common.collect.FluentIterable.from;
import static org.sonar.ce.task.projectanalysis.component.ComponentVisitor.Order.POST_ORDER;
Profiler p = Profiler.createIfTrace(LOG);
p.start();
- Map<String, Component> reportFilesByKey = getReportFilesByKey(this.rootHolder.getRoot());
- context.getStatistics().add("reportFiles", reportFilesByKey.size());
- if (reportFilesByKey.isEmpty()) {
+ Map<String, Component> reportFilesByUuid = getReportFilesByUuid(this.rootHolder.getRoot());
+ context.getStatistics().add("reportFiles", reportFilesByUuid.size());
+ if (reportFilesByUuid.isEmpty()) {
LOG.debug("No files in report. No file move detection.");
return;
}
- Map<String, DbComponent> dbFilesByKey = getDbFilesByKey();
- context.getStatistics().add("dbFiles", dbFilesByKey.size());
+ Map<String, DbComponent> dbFilesByUuid = getDbFilesByUuid();
+ context.getStatistics().add("dbFiles", dbFilesByUuid.size());
- Set<String> addedFileKeys = difference(reportFilesByKey.keySet(), dbFilesByKey.keySet());
- context.getStatistics().add("addedFiles", addedFileKeys.size());
+ Set<String> addedFileUuids = difference(reportFilesByUuid.keySet(), dbFilesByUuid.keySet());
+ context.getStatistics().add("addedFiles", addedFileUuids.size());
- if (dbFilesByKey.isEmpty()) {
- registerAddedFiles(addedFileKeys, reportFilesByKey, null);
+ if (dbFilesByUuid.isEmpty()) {
+ registerAddedFiles(addedFileUuids, reportFilesByUuid, null);
LOG.debug("Previous snapshot has no file. No file move detection.");
return;
}
- Set<String> removedFileKeys = difference(dbFilesByKey.keySet(), reportFilesByKey.keySet());
+ Set<String> removedFileUuids = difference(dbFilesByUuid.keySet(), reportFilesByUuid.keySet());
// can find matches if at least one of the added or removed files groups is empty => abort
- if (addedFileKeys.isEmpty() || removedFileKeys.isEmpty()) {
- registerAddedFiles(addedFileKeys, reportFilesByKey, null);
+ if (addedFileUuids.isEmpty() || removedFileUuids.isEmpty()) {
+ registerAddedFiles(addedFileUuids, reportFilesByUuid, null);
LOG.debug("Either no files added or no files removed. Do nothing.");
return;
}
// retrieve file data from report
- Map<String, File> reportFileSourcesByKey = getReportFileSourcesByKey(reportFilesByKey, addedFileKeys);
+ Map<String, File> reportFileSourcesByUuid = getReportFileSourcesByUuid(reportFilesByUuid, addedFileUuids);
p.stopTrace("loaded");
// compute score matrix
p.start();
- ScoreMatrix scoreMatrix = computeScoreMatrix(dbFilesByKey, removedFileKeys, reportFileSourcesByKey);
+ ScoreMatrix scoreMatrix = computeScoreMatrix(dbFilesByUuid, removedFileUuids, reportFileSourcesByUuid);
p.stopTrace("Score matrix computed");
scoreMatrixDumper.dumpAsCsv(scoreMatrix);
// not a single match with score higher than MIN_REQUIRED_SCORE => abort
if (scoreMatrix.getMaxScore() < MIN_REQUIRED_SCORE) {
context.getStatistics().add("movedFiles", 0);
- registerAddedFiles(addedFileKeys, reportFilesByKey, null);
+ registerAddedFiles(addedFileUuids, reportFilesByUuid, null);
LOG.debug("max score in matrix is less than min required score ({}). Do nothing.", MIN_REQUIRED_SCORE);
return;
}
p.start();
MatchesByScore matchesByScore = MatchesByScore.create(scoreMatrix);
- ElectedMatches electedMatches = electMatches(removedFileKeys, reportFileSourcesByKey, matchesByScore);
+ ElectedMatches electedMatches = electMatches(removedFileUuids, reportFileSourcesByUuid, matchesByScore);
p.stopTrace("Matches elected");
context.getStatistics().add("movedFiles", electedMatches.size());
- registerMatches(dbFilesByKey, reportFilesByKey, electedMatches);
- registerAddedFiles(addedFileKeys, reportFilesByKey, electedMatches);
+ registerMatches(dbFilesByUuid, reportFilesByUuid, electedMatches);
+ registerAddedFiles(addedFileUuids, reportFilesByUuid, electedMatches);
}
public Set<String> difference(Set<String> set1, Set<String> set2) {
return Sets.difference(set1, set2).immutableCopy();
}
- private void registerMatches(Map<String, DbComponent> dbFilesByKey, Map<String, Component> reportFilesByKey, ElectedMatches electedMatches) {
+ private void registerMatches(Map<String, DbComponent> dbFilesByUuid, Map<String, Component> reportFilesByUuid, ElectedMatches electedMatches) {
LOG.debug("{} files moves found", electedMatches.size());
for (Match validatedMatch : electedMatches) {
movedFilesRepository.setOriginalFile(
- reportFilesByKey.get(validatedMatch.getReportKey()),
- toOriginalFile(dbFilesByKey.get(validatedMatch.getDbKey())));
+ reportFilesByUuid.get(validatedMatch.getReportUuid()),
+ toOriginalFile(dbFilesByUuid.get(validatedMatch.getDbUuid())));
LOG.trace("File move found: {}", validatedMatch);
}
}
- private void registerAddedFiles(Set<String> addedFileKeys, Map<String, Component> reportFilesByKey, @Nullable ElectedMatches electedMatches) {
+ private void registerAddedFiles(Set<String> addedFileUuids, Map<String, Component> reportFilesByUuid, @Nullable ElectedMatches electedMatches) {
if (electedMatches == null || electedMatches.isEmpty()) {
- addedFileKeys.stream()
- .map(reportFilesByKey::get)
+ addedFileUuids.stream()
+ .map(reportFilesByUuid::get)
.forEach(addedFileRepository::register);
} else {
- Set<String> reallyAddedFileKeys = new HashSet<>(addedFileKeys);
+ Set<String> reallyAddedFileUuids = new HashSet<>(addedFileUuids);
for (Match electedMatch : electedMatches) {
- reallyAddedFileKeys.remove(electedMatch.getReportKey());
+ reallyAddedFileUuids.remove(electedMatch.getReportUuid());
}
- reallyAddedFileKeys.stream()
- .map(reportFilesByKey::get)
+ reallyAddedFileUuids.stream()
+ .map(reportFilesByUuid::get)
.forEach(addedFileRepository::register);
}
}
- private Map<String, DbComponent> getDbFilesByKey() {
+ private Map<String, DbComponent> getDbFilesByUuid() {
try (DbSession dbSession = dbClient.openSession(false)) {
ImmutableList.Builder<DbComponent> builder = ImmutableList.builder();
dbClient.componentDao().scrollAllFilesForFileMove(dbSession, rootHolder.getRoot().getUuid(),
builder.add(new DbComponent(row.getId(), row.getKey(), row.getUuid(), row.getPath(), row.getLineCount()));
});
return builder.build().stream()
- .collect(MoreCollectors.uniqueIndex(DbComponent::getKey));
+ .collect(MoreCollectors.uniqueIndex(DbComponent::getUuid));
}
}
- private static Map<String, Component> getReportFilesByKey(Component root) {
+ private static Map<String, Component> getReportFilesByUuid(Component root) {
final ImmutableMap.Builder<String, Component> builder = ImmutableMap.builder();
new DepthTraversalTypeAwareCrawler(
new TypeAwareVisitorAdapter(CrawlerDepthLimit.FILE, POST_ORDER) {
@Override
public void visitFile(Component file) {
- builder.put(file.getDbKey(), file);
+ builder.put(file.getUuid(), file);
}
}).visit(root);
return builder.build();
}
- private Map<String, File> getReportFileSourcesByKey(Map<String, Component> reportFilesByKey, Set<String> addedFileKeys) {
+ private Map<String, File> getReportFileSourcesByUuid(Map<String, Component> reportFilesByUuid, Set<String> addedFileUuids) {
ImmutableMap.Builder<String, File> builder = ImmutableMap.builder();
- for (String fileKey : addedFileKeys) {
- Component component = reportFilesByKey.get(fileKey);
+ for (String fileUuid : addedFileUuids) {
+ Component component = reportFilesByUuid.get(fileUuid);
File file = new LazyFileImpl(
component.getName(),
() -> getReportFileLineHashes(component),
component.getFileAttributes().getLines());
- builder.put(fileKey, file);
+ builder.put(fileUuid, file);
}
return builder.build();
}
return sourceLinesHash.getLineHashesMatchingDBVersion(component);
}
- private ScoreMatrix computeScoreMatrix(Map<String, DbComponent> dtosByKey, Set<String> removedFileKeys, Map<String, File> newFileSourcesByKey) {
- ScoreMatrix.ScoreFile[] newFiles = newFileSourcesByKey.entrySet().stream()
+ private ScoreMatrix computeScoreMatrix(Map<String, DbComponent> dtosByUuid, Set<String> removedFileUuids, Map<String, File> newFileSourcesByUuid) {
+ ScoreMatrix.ScoreFile[] newFiles = newFileSourcesByUuid.entrySet().stream()
.map(e -> new ScoreMatrix.ScoreFile(e.getKey(), e.getValue().getLineCount()))
.toArray(ScoreMatrix.ScoreFile[]::new);
- ScoreMatrix.ScoreFile[] removedFiles = removedFileKeys.stream()
+ ScoreMatrix.ScoreFile[] removedFiles = removedFileUuids.stream()
.map(key -> {
- DbComponent dbComponent = dtosByKey.get(key);
- return new ScoreMatrix.ScoreFile(dbComponent.getKey(), dbComponent.getLineCount());
+ DbComponent dbComponent = dtosByUuid.get(key);
+ return new ScoreMatrix.ScoreFile(dbComponent.getUuid(), dbComponent.getLineCount());
})
.toArray(ScoreMatrix.ScoreFile[]::new);
// sort by highest line count first
int[][] scoreMatrix = new int[removedFiles.length][newFiles.length];
int lastNewFileIndex = newFiles.length - 1;
- Map<String, Integer> removedFilesIndexes = new HashMap<>(removedFileKeys.size());
+ Map<String, Integer> removedFilesIndexes = new HashMap<>(removedFileUuids.size());
for (int removeFileIndex = 0; removeFileIndex < removedFiles.length; removeFileIndex++) {
ScoreMatrix.ScoreFile removedFile = removedFiles[removeFileIndex];
int lowerBound = (int) Math.floor(removedFile.getLineCount() * LOWER_BOUND_RATIO);
if (newFiles[0].getLineCount() <= lowerBound || newFiles[lastNewFileIndex].getLineCount() >= upperBound) {
continue;
}
- removedFilesIndexes.put(removedFile.getFileKey(), removeFileIndex);
+ removedFilesIndexes.put(removedFile.getFileUuid(), removeFileIndex);
}
LineHashesWithKeyDtoResultHandler rowHandler = new LineHashesWithKeyDtoResultHandler(removedFilesIndexes, removedFiles,
- newFiles, newFileSourcesByKey, scoreMatrix);
+ newFiles, newFileSourcesByUuid, scoreMatrix);
try (DbSession dbSession = dbClient.openSession(false)) {
dbClient.fileSourceDao().scrollLineHashes(dbSession, removedFilesIndexes.keySet(), rowHandler);
}
return new ScoreMatrix(removedFiles, newFiles, scoreMatrix, rowHandler.getMaxScore());
}
- private final class LineHashesWithKeyDtoResultHandler implements ResultHandler<LineHashesWithKeyDto> {
+ private final class LineHashesWithKeyDtoResultHandler implements ResultHandler<LineHashesWithUuidDto> {
private final Map<String, Integer> removedFilesIndexes;
private final ScoreMatrix.ScoreFile[] removedFiles;
private final ScoreMatrix.ScoreFile[] newFiles;
}
@Override
- public void handleResult(ResultContext<? extends LineHashesWithKeyDto> resultContext) {
- LineHashesWithKeyDto lineHashesDto = resultContext.getResultObject();
+ public void handleResult(ResultContext<? extends LineHashesWithUuidDto> resultContext) {
+ LineHashesWithUuidDto lineHashesDto = resultContext.getResultObject();
if (lineHashesDto.getPath() == null) {
return;
}
- int removeFileIndex = removedFilesIndexes.get(lineHashesDto.getKey());
+ int removeFileIndex = removedFilesIndexes.get(lineHashesDto.getUuid());
ScoreMatrix.ScoreFile removedFile = removedFiles[removeFileIndex];
int lowerBound = (int) Math.floor(removedFile.getLineCount() * LOWER_BOUND_RATIO);
int upperBound = (int) Math.ceil(removedFile.getLineCount() * UPPER_BOUND_RATIO);
}
File fileInDb = new FileImpl(lineHashesDto.getPath(), lineHashesDto.getLineHashes());
- File unmatchedFile = newFileSourcesByKey.get(newFile.getFileKey());
+ File unmatchedFile = newFileSourcesByKey.get(newFile.getFileUuid());
int score = fileSimilarity.score(fileInDb, unmatchedFile);
scoreMatrix[removeFileIndex][newFileIndex] = score;
if (score > maxScore) {
}
}
- private static ElectedMatches electMatches(Set<String> dbFileKeys, Map<String, File> reportFileSourcesByKey, MatchesByScore matchesByScore) {
- ElectedMatches electedMatches = new ElectedMatches(matchesByScore, dbFileKeys, reportFileSourcesByKey);
+ private static ElectedMatches electMatches(Set<String> dbFileUuids, Map<String, File> reportFileSourcesByUuid, MatchesByScore matchesByScore) {
+ ElectedMatches electedMatches = new ElectedMatches(matchesByScore, dbFileUuids, reportFileSourcesByUuid);
Multimap<String, Match> matchesPerFileForScore = ArrayListMultimap.create();
matchesByScore.forEach(matches -> electMatches(matches, electedMatches, matchesPerFileForScore));
return electedMatches;
} else {
matchesPerFileForScore.clear();
for (Match match : matchesToValidate) {
- matchesPerFileForScore.put(match.getDbKey(), match);
- matchesPerFileForScore.put(match.getReportKey(), match);
+ matchesPerFileForScore.put(match.getDbUuid(), match);
+ matchesPerFileForScore.put(match.getReportUuid(), match);
}
// validate non ambiguous matches (ie. the match is the only match of either the db file and the report file)
for (Match match : matchesToValidate) {
- int dbFileMatchesCount = matchesPerFileForScore.get(match.getDbKey()).size();
- int reportFileMatchesCount = matchesPerFileForScore.get(match.getReportKey()).size();
+ int dbFileMatchesCount = matchesPerFileForScore.get(match.getDbUuid()).size();
+ int reportFileMatchesCount = matchesPerFileForScore.get(match.getReportUuid()).size();
if (dbFileMatchesCount == 1 && reportFileMatchesCount == 1) {
electedMatches.add(match);
}
private static class ElectedMatches implements Iterable<Match> {
private final List<Match> matches;
- private final Set<String> matchedFileKeys;
+ private final Set<String> matchedFileUuids;
- public ElectedMatches(MatchesByScore matchesByScore, Set<String> dbFileKeys, Map<String, File> reportFileSourcesByKey) {
+ public ElectedMatches(MatchesByScore matchesByScore, Set<String> dbFileUuids, Map<String, File> reportFileSourcesByUuid) {
this.matches = new ArrayList<>(matchesByScore.getSize());
- this.matchedFileKeys = new HashSet<>(dbFileKeys.size() + reportFileSourcesByKey.size());
+ this.matchedFileUuids = new HashSet<>(dbFileUuids.size() + reportFileSourcesByUuid.size());
}
public void add(Match match) {
matches.add(match);
- matchedFileKeys.add(match.getDbKey());
- matchedFileKeys.add(match.getReportKey());
+ matchedFileUuids.add(match.getDbUuid());
+ matchedFileUuids.add(match.getReportUuid());
}
public List<Match> filter(Iterable<Match> matches) {
}
private boolean notAlreadyMatched(Match input) {
- return !(matchedFileKeys.contains(input.getDbKey()) || matchedFileKeys.contains(input.getReportKey()));
+ return !(matchedFileUuids.contains(input.getDbUuid()) || matchedFileUuids.contains(input.getReportUuid()));
}
@Override
@Immutable
final class Match {
- private final String dbKey;
- private final String reportKey;
+ private final String dbUuid;
+ private final String reportUuid;
- Match(String dbKey, String reportKey) {
- this.dbKey = dbKey;
- this.reportKey = reportKey;
+ Match(String dbUuid, String reportUuid) {
+ this.dbUuid = dbUuid;
+ this.reportUuid = reportUuid;
}
- public String getDbKey() {
- return dbKey;
+ public String getDbUuid() {
+ return dbUuid;
}
- public String getReportKey() {
- return reportKey;
+ public String getReportUuid() {
+ return reportUuid;
}
@Override
return false;
}
Match match = (Match) o;
- return dbKey.equals(match.dbKey) && reportKey.equals(match.reportKey);
+ return dbUuid.equals(match.dbUuid) && reportUuid.equals(match.reportUuid);
}
@Override
public int hashCode() {
- return Objects.hash(dbKey, reportKey);
+ return Objects.hash(dbUuid, reportUuid);
}
@Override
public String toString() {
- return '{' + dbKey + "=>" + reportKey + '}';
+ return '{' + dbUuid + "=>" + reportUuid + '}';
}
}
if (matches[index] == null) {
matches[index] = new ArrayList<>(1);
}
- Match match = new Match(removedFile.getFileKey(), newFile.getFileKey());
+ Match match = new Match(removedFile.getFileUuid(), newFile.getFileUuid());
matches[index].add(match);
totalMatches++;
}
public String toCsv(char separator) {
StringBuilder res = new StringBuilder();
- // first row: empty column, then one column for each report file (its key)
+ // first row: empty column, then one column for each report file (its uuid)
res.append("newFiles=>").append(separator);
- Arrays.stream(newFiles).forEach(f -> res.append(f.getFileKey()).append('(').append(f.getLineCount()).append(')').append(separator));
- // rows with data: column with db file (its key), then one column for each value
+ Arrays.stream(newFiles).forEach(f -> res.append(f.getFileUuid()).append('(').append(f.getLineCount()).append(')').append(separator));
+ // rows with data: column with db file (its uuid), then one column for each value
accept(new ScoreMatrixVisitor() {
private ScoreFile previousRemovedFile = null;
@Override
public void visit(ScoreFile removedFile, ScoreFile newFile, int score) {
if (previousRemovedFile != removedFile) {
- res.append('\n').append(removedFile.getFileKey()).append('(').append(removedFile.getLineCount()).append(')').append(separator);
+ res.append('\n').append(removedFile.getFileUuid()).append('(').append(removedFile.getLineCount()).append(')').append(separator);
previousRemovedFile = removedFile;
}
res.append(score).append(separator);
}
static class ScoreFile {
- private final String fileKey;
+ private final String fileUuid;
private final int lineCount;
- ScoreFile(String fileKey, int lineCount) {
- this.fileKey = fileKey;
+ ScoreFile(String fileUuid, int lineCount) {
+ this.fileUuid = fileUuid;
this.lineCount = lineCount;
}
- public String getFileKey() {
- return fileKey;
+ public String getFileUuid() {
+ return fileUuid;
}
public int getLineCount() {
import org.sonar.ce.task.projectanalysis.source.SourceLinesHashRepository;
import org.sonar.ce.task.step.TestComputationStepContext;
import org.sonar.core.hash.SourceLineHashesComputer;
-import org.sonar.core.util.UuidFactoryFast;
import org.sonar.db.DbClient;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
analysisMetadataHolder.setBaseAnalysis(ANALYSIS);
Component file1 = fileComponent(FILE_1_REF, null);
Component file2 = fileComponent(FILE_2_REF, null);
- insertFiles(file1.getDbKey(), file2.getDbKey());
- insertContentOfFileInDb(file1.getDbKey(), CONTENT1);
- insertContentOfFileInDb(file2.getDbKey(), CONTENT2);
+ insertFiles(file1.getUuid(), file2.getUuid());
+ insertContentOfFileInDb(file1.getUuid(), CONTENT1);
+ insertContentOfFileInDb(file2.getUuid(), CONTENT2);
setFilesInReport(file2, file1);
TestComputationStepContext context = new TestComputationStepContext();
analysisMetadataHolder.setBaseAnalysis(ANALYSIS);
Component file1 = fileComponent(FILE_1_REF, null);
Component file2 = fileComponent(FILE_2_REF, CONTENT1);
- ComponentDto[] dtos = insertFiles(file1.getDbKey());
- insertContentOfFileInDb(file1.getDbKey(), CONTENT1);
+ ComponentDto[] dtos = insertFiles(file1.getUuid());
+ insertContentOfFileInDb(file1.getUuid(), CONTENT1);
setFilesInReport(file2);
TestComputationStepContext context = new TestComputationStepContext();
Component file1 = fileComponent(FILE_1_REF, null);
Component file2 = fileComponent(FILE_2_REF, null);
Component file3 = fileComponent(FILE_3_REF, CONTENT1);
- insertFiles(file1.getDbKey(), file2.getDbKey());
- insertContentOfFileInDb(file1.getDbKey(), CONTENT1);
- insertContentOfFileInDb(file2.getDbKey(), CONTENT1);
+ insertFiles(file1.getUuid(), file2.getUuid());
+ insertContentOfFileInDb(file1.getUuid(), CONTENT1);
+ insertContentOfFileInDb(file2.getUuid(), CONTENT1);
setFilesInReport(file3);
TestComputationStepContext context = new TestComputationStepContext();
analysisMetadataHolder.setBaseAnalysis(ANALYSIS);
Component file1 = fileComponent(FILE_1_REF, null);
Component file2 = fileComponent(FILE_2_REF, null);
- insertFiles(file1.getDbKey(), file2.getDbKey());
- insertContentOfFileInDb(file1.getDbKey(), null);
- insertContentOfFileInDb(file2.getDbKey(), null);
+ insertFiles(file1.getUuid(), file2.getUuid());
+ insertContentOfFileInDb(file1.getUuid(), null);
+ insertContentOfFileInDb(file2.getUuid(), null);
setFilesInReport(file1, file2);
TestComputationStepContext context = new TestComputationStepContext();
Component file4 = fileComponent(5, new String[] {"a", "b"});
Component file5 = fileComponent(6, null);
Component file6 = fileComponent(7, LESS_CONTENT2);
- ComponentDto[] dtos = insertFiles(file1.getDbKey(), file2.getDbKey(), file4.getDbKey(), file5.getDbKey());
- insertContentOfFileInDb(file1.getDbKey(), CONTENT1);
- insertContentOfFileInDb(file2.getDbKey(), LESS_CONTENT1);
- insertContentOfFileInDb(file4.getDbKey(), new String[] {"e", "f", "g", "h", "i"});
- insertContentOfFileInDb(file5.getDbKey(), CONTENT2);
+ ComponentDto[] dtos = insertFiles(file1.getUuid(), file2.getUuid(), file4.getUuid(), file5.getUuid());
+ insertContentOfFileInDb(file1.getUuid(), CONTENT1);
+ insertContentOfFileInDb(file2.getUuid(), LESS_CONTENT1);
+ insertContentOfFileInDb(file4.getUuid(), new String[] {"e", "f", "g", "h", "i"});
+ insertContentOfFileInDb(file5.getUuid(), CONTENT2);
setFilesInReport(file3, file4, file6);
TestComputationStepContext context = new TestComputationStepContext();
public void real_life_use_case() throws Exception {
analysisMetadataHolder.setBaseAnalysis(ANALYSIS);
for (File f : FileUtils.listFiles(new File("src/test/resources/org/sonar/ce/task/projectanalysis/filemove/FileMoveDetectionStepTest/v1"), null, false)) {
- insertFiles(f.getName());
- insertContentOfFileInDb(f.getName(), readLines(f));
+ insertFiles("uuid_" + f.getName().hashCode());
+ insertContentOfFileInDb("uuid_" + f.getName().hashCode(), readLines(f));
}
Map<String, Component> comps = new HashMap<>();
for (File f : FileUtils.listFiles(new File("src/test/resources/org/sonar/ce/task/projectanalysis/filemove/FileMoveDetectionStepTest/v2"), null, false)) {
String[] lines = readLines(f);
Component c = builder(Component.Type.FILE, i++)
+ .setUuid("uuid_" + f.getName().hashCode())
.setKey(f.getName())
.setName(f.getName())
.setFileAttributes(new FileAttributes(false, null, lines.length))
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");
+ assertThat(movedFilesRepository.getOriginalFile(makeComponentUuidAndAnalysisUuidNotNullOnDuplicationsIndex).get().getUuid())
+ .isEqualTo("uuid_" + "MakeComponentUuidNotNullOnDuplicationsIndex.java".hashCode());
+ assertThat(movedFilesRepository.getOriginalFile(migrationRb1238).get().getUuid())
+ .isEqualTo("uuid_" + "1242_make_analysis_uuid_not_null_on_duplications_index.rb".hashCode());
+ assertThat(movedFilesRepository.getOriginalFile(addComponentUuidAndAnalysisUuidColumnToDuplicationsIndex).get().getUuid())
+ .isEqualTo("uuid_" + "AddComponentUuidColumnToDuplicationsIndex.java".hashCode());
verifyStatistics(context, comps.values().size(), 12, 6, 3);
}
}
@CheckForNull
- private FileSourceDto insertContentOfFileInDb(String key, @Nullable String[] content) {
- return dbTester.getDbClient().componentDao().selectByKey(dbTester.getSession(), key)
+ private FileSourceDto insertContentOfFileInDb(String uuid, @Nullable String[] content) {
+ return dbTester.getDbClient().componentDao().selectByUuid(dbTester.getSession(), uuid)
.map(file -> {
SourceLineHashesComputer linesHashesComputer = new SourceLineHashesComputer();
if (content != null) {
.build());
}
- private ComponentDto[] insertFiles(String... componentKeys) {
- return insertFiles(this::newComponentDto, componentKeys);
+ private ComponentDto[] insertFiles(String... uuids) {
+ return insertFiles(this::newComponentDto, uuids);
}
- private ComponentDto[] insertFiles(Function<String, ComponentDto> newComponentDto, String... componentKeys) {
- return stream(componentKeys)
+ private ComponentDto[] insertFiles(Function<String, ComponentDto> newComponentDto, String... uuids) {
+ return stream(uuids)
.map(newComponentDto)
.map(dto -> dbTester.components().insertComponent(dto))
.toArray(ComponentDto[]::new);
}
- private ComponentDto newComponentDto(String key) {
+ private ComponentDto newComponentDto(String uuid) {
return ComponentTesting.newFileDto(project)
- .setDbKey(key)
- .setUuid(UuidFactoryFast.getInstance().create())
- .setPath("path_" + key);
+ .setDbKey("key_" + uuid)
+ .setUuid(uuid)
+ .setPath("path_" + uuid);
}
private Component fileComponent(int ref, @Nullable String[] content) {
@Test
public void getDbKey_returns_first_constructor_argument() {
- assertThat(underTest.getDbKey()).isEqualTo(SOME_KEY);
+ assertThat(underTest.getDbUuid()).isEqualTo(SOME_KEY);
}
@Test
public void getDbKey_returns_second_constructor_argument() {
- assertThat(underTest.getReportKey()).isEqualTo(SOME_REPORT_KEY);
+ assertThat(underTest.getReportUuid()).isEqualTo(SOME_REPORT_KEY);
}
@Test
/**
* Scroll line hashes of all <strong>enabled</strong> components (should be files, but not enforced) with specified
- * keys in no specific order with 'SOURCE' source and a non null path.
+ * uuids in no specific order with 'SOURCE' source and a non null path.
*/
- public void scrollLineHashes(DbSession dbSession, Collection<String> fileKeys, ResultHandler<LineHashesWithKeyDto> rowHandler) {
- for (List<String> partition : toUniqueAndSortedPartitions(fileKeys)) {
+ public void scrollLineHashes(DbSession dbSession, Collection<String> fileUUids, ResultHandler<LineHashesWithUuidDto> rowHandler) {
+ for (List<String> partition : toUniqueAndSortedPartitions(fileUUids)) {
mapper(dbSession).scrollLineHashes(partition, rowHandler);
}
}
@CheckForNull
FileSourceDto select(@Param("fileUuid") String fileUuid, @Param("dataType") String dataType);
- void scrollLineHashes(@Param("fileKeys") Collection<String> fileKeys, ResultHandler<LineHashesWithKeyDto> rowHandler);
+ void scrollLineHashes(@Param("fileUuids") Collection<String> fileUuids, ResultHandler<LineHashesWithUuidDto> rowHandler);
@CheckForNull
Integer selectLineHashesVersion(@Param("fileUuid") String fileUuid, @Param("dataType") String dataType);
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2019 SonarSource SA
- * mailto:info 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.source;
-
-import java.util.Collections;
-import java.util.List;
-import javax.annotation.Nullable;
-
-import static org.sonar.db.source.FileSourceDto.LINES_HASHES_SPLITTER;
-
-public class LineHashesWithKeyDto {
- private String kee;
- private String path;
- private String lineHashes;
-
- public String getKey() {
- return kee;
- }
-
- public String getPath() {
- return path;
- }
-
- /** Used by MyBatis */
- public String getRawLineHashes() {
- return lineHashes;
- }
-
- /** Used by MyBatis */
- public void setRawLineHashes(@Nullable String lineHashes) {
- this.lineHashes = lineHashes;
- }
-
- public List<String> getLineHashes() {
- if (lineHashes == null) {
- return Collections.emptyList();
- }
- return LINES_HASHES_SPLITTER.splitToList(lineHashes);
- }
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 SonarSource SA
+ * mailto:info 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.source;
+
+import java.util.Collections;
+import java.util.List;
+import javax.annotation.Nullable;
+
+import static org.sonar.db.source.FileSourceDto.LINES_HASHES_SPLITTER;
+
+public class LineHashesWithUuidDto {
+ private String uuid;
+ private String path;
+ private String lineHashes;
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ /** Used by MyBatis */
+ public String getRawLineHashes() {
+ return lineHashes;
+ }
+
+ /** Used by MyBatis */
+ public void setRawLineHashes(@Nullable String lineHashes) {
+ this.lineHashes = lineHashes;
+ }
+
+ public List<String> getLineHashes() {
+ if (lineHashes == null) {
+ return Collections.emptyList();
+ }
+ return LINES_HASHES_SPLITTER.splitToList(lineHashes);
+ }
+}
and data_type = #{dataType,jdbcType=VARCHAR}
</select>
- <select id="scrollLineHashes" parameterType="map" resultType="org.sonar.db.source.LineHashesWithKeyDto" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
+ <select id="scrollLineHashes" parameterType="map" resultType="org.sonar.db.source.LineHashesWithUuidDto" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY">
select
- p.kee as kee,
+ p.uuid as uuid,
p.path as path,
fs.line_hashes as rawLineHashes
from projects p
fs.file_uuid = p.uuid
and fs.data_type = 'SOURCE'
where
- p.kee in
- <foreach collection="fileKeys" item="fileKey" open="(" close=")" separator=",">
- #{fileKey,jdbcType=VARCHAR}
+ p.uuid in
+ <foreach collection="fileUuids" item="fileUuid" open="(" close=")" separator=",">
+ #{fileUuid,jdbcType=VARCHAR}
</foreach>
and p.path is not null
</select>
}
@Test
- public void scrollLineHashes_has_no_effect_if_no_keys() {
+ public void scrollLineHashes_has_no_effect_if_no_uuids() {
underTest.scrollLineHashes(dbSession, emptySet(), resultContext -> fail("handler should not be called"));
}
ComponentDto file3 = dbTester.components().insertComponent(newFileDto(project));
FileSourceDto fileSource3 = dbTester.fileSources().insertFileSource(file3);
- LineHashesWithKeyDtoHandler handler = scrollLineHashes(file1.getDbKey());
+ LineHashesWithKeyDtoHandler handler = scrollLineHashes(file1.uuid());
assertThat(handler.dtos).hasSize(1);
verifyLinesHashes(handler, file1, fileSource1);
- handler = scrollLineHashes(file2.getDbKey());
+ handler = scrollLineHashes(file2.uuid());
assertThat(handler.dtos).hasSize(1);
verifyLinesHashes(handler, file2, fileSource2);
- handler = scrollLineHashes(file2.getDbKey(), file1.getDbKey(), file3.getDbKey());
+ handler = scrollLineHashes(file2.uuid(), file1.uuid(), file3.uuid());
assertThat(handler.dtos).hasSize(3);
verifyLinesHashes(handler, file1, fileSource1);
verifyLinesHashes(handler, file2, fileSource2);
ComponentDto file2 = dbTester.components().insertComponent(newFileDto(project).setPath(null));
FileSourceDto fileSource2 = dbTester.fileSources().insertFileSource(file2);
- LineHashesWithKeyDtoHandler handler = scrollLineHashes(file2.getDbKey(), file1.getDbKey());
+ LineHashesWithKeyDtoHandler handler = scrollLineHashes(file2.uuid(), file1.uuid());
assertThat(handler.dtos).hasSize(1);
verifyLinesHashes(handler, file1, fileSource1);
}
FileSourceDto fileSource3 = dbTester.fileSources().insertFileSource(file3, t -> t.setDataType(Type.SOURCE));
FileSourceDto testFileSource3 = dbTester.fileSources().insertFileSource(file3, t -> t.setDataType(Type.TEST));
- LineHashesWithKeyDtoHandler handler = scrollLineHashes(file2.getDbKey(), file1.getDbKey(), file3.getDbKey());
+ LineHashesWithKeyDtoHandler handler = scrollLineHashes(file2.uuid(), file1.uuid(), file3.uuid());
assertThat(handler.dtos).hasSize(2);
verifyLinesHashes(handler, file1, fileSource1);
verifyLinesHashes(handler, file3, fileSource3);
.collect(Collectors.toList());
LineHashesWithKeyDtoHandler handler = new LineHashesWithKeyDtoHandler();
- underTest.scrollLineHashes(dbSession, files.stream().map(ComponentDto::getDbKey).collect(Collectors.toSet()), handler);
+ underTest.scrollLineHashes(dbSession, files.stream().map(ComponentDto::uuid).collect(Collectors.toSet()), handler);
assertThat(handler.dtos).hasSize(files.size());
- files.forEach(t -> assertThat(handler.getByKey(t.getDbKey())).isPresent());
+ files.forEach(t -> assertThat(handler.getByUuid(t.uuid())).isPresent());
}
- private LineHashesWithKeyDtoHandler scrollLineHashes(String... keys) {
+ private LineHashesWithKeyDtoHandler scrollLineHashes(String... uuids) {
LineHashesWithKeyDtoHandler handler = new LineHashesWithKeyDtoHandler();
- underTest.scrollLineHashes(dbSession, ImmutableSet.copyOf(keys), handler);
+ underTest.scrollLineHashes(dbSession, ImmutableSet.copyOf(uuids), handler);
return handler;
}
private static void verifyLinesHashes(LineHashesWithKeyDtoHandler handler, ComponentDto file, FileSourceDto fileSource) {
- LineHashesWithKeyDto dto = handler.getByKey(file.getDbKey()).get();
+ LineHashesWithUuidDto dto = handler.getByUuid(file.uuid()).get();
assertThat(dto.getPath()).isEqualTo(file.path());
assertThat(dto.getRawLineHashes()).isEqualTo(fileSource.getRawLineHashes());
assertThat(dto.getLineHashes()).isEqualTo(fileSource.getLineHashes());
}
- private static final class LineHashesWithKeyDtoHandler implements ResultHandler<LineHashesWithKeyDto> {
- private final List<LineHashesWithKeyDto> dtos = new ArrayList<>();
+ private static final class LineHashesWithKeyDtoHandler implements ResultHandler<LineHashesWithUuidDto> {
+ private final List<LineHashesWithUuidDto> dtos = new ArrayList<>();
@Override
- public void handleResult(ResultContext<? extends LineHashesWithKeyDto> resultContext) {
+ public void handleResult(ResultContext<? extends LineHashesWithUuidDto> resultContext) {
dtos.add(resultContext.getResultObject());
}
- public Optional<LineHashesWithKeyDto> getByKey(String key) {
+ public Optional<LineHashesWithUuidDto> getByUuid(String uuid) {
return dtos.stream()
- .filter(t -> key.equals(t.getKey()))
+ .filter(t -> uuid.equals(t.getUuid()))
.findAny();
}
}