Browse Source

SONAR-9616 Renaming of project/module key must be propagated to branches (#2383)

tags/6.6-RC1
Janos Gyerik 6 years ago
parent
commit
0b11b278fd

+ 1
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java View File

@@ -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<String> split = BRANCH_KEY_SPLITTER.splitToList(kee);
return split.size() == 2 ? split.get(1) : null;
}

+ 32
- 1
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java View File

@@ -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<ResourceDto> 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<ResourceDto> modules = collectAllModules(projectUuid, stringToReplace, mapper);

// add branches
Map<String, String> branchBaseKeys = new HashMap<>();
session.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid)
.stream()
.filter(branch -> !projectUuid.equals(branch.getUuid()))
.forEach(branch -> {
Set<ResourceDto> 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<ResourceDto, List<ResourceDto>> 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<ResourceDto> 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<ResourceDto> resources, String oldKey, String newKey, ComponentKeyUpdaterMapper mapper) {
for (ResourceDto resource : resources) {
String oldResourceKey = resource.getKey();

+ 60
- 1
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentKeyUpdaterDaoTest.java View File

@@ -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");

Loading…
Cancel
Save