From 0b11b278fde4daaf3c928a24a2aa3bab21a9982c Mon Sep 17 00:00:00 2001 From: Janos Gyerik Date: Mon, 21 Aug 2017 16:26:57 +0200 Subject: [PATCH] SONAR-9616 Renaming of project/module key must be propagated to branches (#2383) --- .../org/sonar/db/component/ComponentDto.java | 2 +- .../db/component/ComponentKeyUpdaterDao.java | 33 +++++++++- .../component/ComponentKeyUpdaterDaoTest.java | 61 ++++++++++++++++++- 3 files changed, 93 insertions(+), 3 deletions(-) diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java index 9082e9710f0..6d00aff0956 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java @@ -236,7 +236,7 @@ public class ComponentDto { * @return the key of the branch. It will be null on the main branch and when the component is not on a branch */ @CheckForNull - public String getBranch(){ + public String getBranch() { List split = BRANCH_KEY_SPLITTER.splitToList(kee); return split.size() == 2 ? split.get(1) : null; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java index c001028bcf6..505618562c1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java @@ -24,6 +24,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -60,6 +61,15 @@ public class ComponentKeyUpdaterDao implements Dao { List resources = mapper.selectProjectResources(projectOrModuleUuid); resources.add(project); + // add branch components + dbSession.getMapper(BranchMapper.class).selectByProjectUuid(projectOrModuleUuid) + .stream() + .filter(branch -> !projectOrModuleUuid.equals(branch.getUuid())) + .forEach(branch -> { + resources.addAll(mapper.selectProjectResources(branch.getUuid())); + resources.add(mapper.selectProject(branch.getUuid())); + }); + // and then proceed with the batch UPDATE at once runBatchUpdateForAllResources(resources, projectOldKey, newKey, mapper); } @@ -100,6 +110,18 @@ public class ComponentKeyUpdaterDao implements Dao { ComponentKeyUpdaterMapper mapper = session.getMapper(ComponentKeyUpdaterMapper.class); // must SELECT first everything Set modules = collectAllModules(projectUuid, stringToReplace, mapper); + + // add branches + Map branchBaseKeys = new HashMap<>(); + session.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid) + .stream() + .filter(branch -> !projectUuid.equals(branch.getUuid())) + .forEach(branch -> { + Set branchModules = collectAllModules(branch.getUuid(), stringToReplace, mapper); + modules.addAll(branchModules); + branchModules.forEach(module -> branchBaseKeys.put(module.getKey(), branchBaseKey(module.getKey()))); + }); + checkNewNameOfAllModules(modules, stringToReplace, replacementString, mapper); Map> allResourcesByModuleMap = Maps.newHashMap(); for (ResourceDto module : modules) { @@ -109,13 +131,22 @@ public class ComponentKeyUpdaterDao implements Dao { // and then proceed with the batch UPDATE at once for (ResourceDto module : modules) { String oldModuleKey = module.getKey(); - String newModuleKey = computeNewKey(module.getKey(), stringToReplace, replacementString); + oldModuleKey = branchBaseKeys.getOrDefault(oldModuleKey, oldModuleKey); + String newModuleKey = computeNewKey(oldModuleKey, stringToReplace, replacementString); Collection resources = Lists.newArrayList(module); resources.addAll(allResourcesByModuleMap.get(module)); runBatchUpdateForAllResources(resources, oldModuleKey, newModuleKey, mapper); } } + private static String branchBaseKey(String key) { + int index = key.lastIndexOf(ComponentDto.BRANCH_KEY_SEPARATOR); + if (index == -1) { + return key; + } + return key.substring(0, index); + } + private static void runBatchUpdateForAllResources(Collection resources, String oldKey, String newKey, ComponentKeyUpdaterMapper mapper) { for (ResourceDto resource : resources) { String oldResourceKey = resource.getKey(); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java index d1594f7f504..665179c62b6 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java @@ -62,7 +62,7 @@ public class ComponentKeyUpdaterDaoTest { } @Test - public void updateKey_does_not_updated_inactive_components() { + public void updateKey_does_not_update_inactive_components() { OrganizationDto organizationDto = db.organizations().insert(); ComponentDto project = db.components().insertComponent(newPrivateProjectDto(organizationDto, "A").setDbKey("my_project")); ComponentDto directory = db.components().insertComponent(newDirectory(project, "/directory").setDbKey("my_project:directory")); @@ -78,6 +78,65 @@ public class ComponentKeyUpdaterDaoTest { .containsOnlyOnce("your_project", "your_project:directory", "your_project:directory/file", "my_project:inactive_directory", "my_project:inactive_directory/file"); } + @Test + public void updateKey_updates_branches_too() { + ComponentDto project = db.components().insertMainBranch(); + ComponentDto branch = db.components().insertProjectBranch(project); + db.components().insertComponent(newFileDto(branch)); + db.components().insertComponent(newFileDto(branch)); + int branchComponentCount = 3; + + String oldProjectKey = project.getKey(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).hasSize(1); + + String oldBranchKey = branch.getDbKey(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount); + + String newProjectKey = "newKey"; + String newBranchKey = ComponentDto.generateBranchKey(newProjectKey, branch.getBranch()); + underTest.updateKey(dbSession, project.uuid(), newProjectKey); + + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).isEmpty(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty(); + + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newProjectKey)).hasSize(1); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newBranchKey)).hasSize(branchComponentCount); + db.select(dbSession, "select kee from projects") + .forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newProjectKey))); + } + + @Test + public void bulk_updateKey_updates_branches_too() { + ComponentDto project = db.components().insertMainBranch(); + ComponentDto branch = db.components().insertProjectBranch(project); + ComponentDto module = db.components().insertComponent(prefixDbKeyWithKey(newModuleDto(branch), project.getKey())); + db.components().insertComponent(prefixDbKeyWithKey(newFileDto(module), module.getKey())); + db.components().insertComponent(prefixDbKeyWithKey(newFileDto(module), module.getKey())); + int branchComponentCount = 4; + + String oldProjectKey = project.getKey(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).hasSize(1); + + String oldBranchKey = branch.getDbKey(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount); + + String newProjectKey = "newKey"; + String newBranchKey = ComponentDto.generateBranchKey(newProjectKey, branch.getBranch()); + underTest.bulkUpdateKey(dbSession, project.uuid(), oldProjectKey, newProjectKey); + + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldProjectKey)).isEmpty(); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty(); + + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newProjectKey)).hasSize(1); + assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newBranchKey)).hasSize(branchComponentCount); + db.select(dbSession, "select kee from projects") + .forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newProjectKey))); + } + + private ComponentDto prefixDbKeyWithKey(ComponentDto componentDto, String key) { + return componentDto.setDbKey(key + ":" + componentDto.getDbKey()); + } + @Test public void updateKey_throws_IAE_if_component_with_specified_key_does_not_exist() { db.prepareDbUnit(getClass(), "shared.xml"); -- 2.39.5