diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2022-09-30 12:23:26 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-10-12 20:03:44 +0000 |
commit | 50b12df3787d87958fcef7fbf8c00598b141f1ee (patch) | |
tree | cbc6fd2927bd89d8f68b84d06e00dd419c4025e5 /server/sonar-db-dao | |
parent | c85e433a567b8580a1fd5e185b4f5bc73b6e53e6 (diff) | |
download | sonarqube-50b12df3787d87958fcef7fbf8c00598b141f1ee.tar.gz sonarqube-50b12df3787d87958fcef7fbf8c00598b141f1ee.zip |
SONAR-17352 Refactor component keys to not include branch suffix
Diffstat (limited to 'server/sonar-db-dao')
16 files changed, 373 insertions, 354 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java index 56f6bae2fd1..687d4e574aa 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java @@ -23,17 +23,14 @@ import com.google.common.collect.Ordering; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.annotation.Nullable; -import org.apache.commons.lang.StringUtils; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.sonar.api.resources.Qualifiers; @@ -45,6 +42,7 @@ import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.ComponentNewValue; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static java.util.Collections.emptyList; import static org.sonar.db.DatabaseUtils.checkThatNotTooManyConditions; import static org.sonar.db.DatabaseUtils.executeLargeInputs; @@ -58,26 +56,9 @@ public class ComponentDao implements Dao { this.auditPersister = auditPersister; } - private static List<ComponentDto> selectByQueryImpl(DbSession session, ComponentQuery query, int offset, int limit) { - if (query.hasEmptySetOfComponents()) { - return emptyList(); - } - checkThatNotTooManyComponents(query); - return mapper(session).selectByQuery(query, new RowBounds(offset, limit)); - } - - private static int countByQueryImpl(DbSession session, ComponentQuery query) { - if (query.hasEmptySetOfComponents()) { - return 0; - } - checkThatNotTooManyComponents(query); - return mapper(session).countByQuery(query); - } - - private static ComponentMapper mapper(DbSession session) { - return session.getMapper(ComponentMapper.class); - } - + /* + * SELECT BY UUID + */ public Optional<ComponentDto> selectByUuid(DbSession session, String uuid) { return Optional.ofNullable(mapper(session).selectByUuid(uuid)); } @@ -86,22 +67,12 @@ public class ComponentDao implements Dao { return selectByUuid(session, uuid).orElseThrow(() -> new RowNotFoundException(String.format("Component with uuid '%s' not found", uuid))); } - /** - * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values - * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values - * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values - */ - public List<ComponentDto> selectByQuery(DbSession dbSession, ComponentQuery query, int offset, int limit) { - return selectByQueryImpl(dbSession, query, offset, limit); + public List<ComponentDto> selectByUuids(DbSession session, Collection<String> uuids) { + return executeLargeInputs(uuids, mapper(session)::selectByUuids); } - /** - * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values - * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values - * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values - */ - public int countByQuery(DbSession session, ComponentQuery query) { - return countByQueryImpl(session, query); + public List<String> selectExistingUuids(DbSession session, Collection<String> uuids) { + return executeLargeInputs(uuids, mapper(session)::selectExistingUuids); } public List<ComponentDto> selectSubProjectsByComponentUuids(DbSession session, Collection<String> uuids) { @@ -127,81 +98,100 @@ public class ComponentDao implements Dao { return mapper(session).selectEnabledFilesFromProject(rootComponentUuid); } - public List<ComponentDto> selectByUuids(DbSession session, Collection<String> uuids) { - return executeLargeInputs(uuids, mapper(session)::selectByUuids); + /** + * Retrieves all components with a specific branch UUID, no other filtering is done by this method. + */ + public List<ComponentDto> selectByBranchUuid(String branchUuid, DbSession dbSession) { + return mapper(dbSession).selectByBranchUuid(branchUuid); } - public List<String> selectExistingUuids(DbSession session, Collection<String> uuids) { - return executeLargeInputs(uuids, mapper(session)::selectExistingUuids); + public int countEnabledModulesByBranchUuid(DbSession session, String branchUuid) { + return mapper(session).countEnabledModulesByBranchUuid(branchUuid); } + /* + SELECT BY QUERY + */ + /** - * Return all components of a project (including disable ones) + * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values + * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values + * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values */ - public List<ComponentDto> selectAllComponentsFromProjectKey(DbSession session, String projectKey) { - return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, null, false); + public List<ComponentDto> selectByQuery(DbSession dbSession, ComponentQuery query, int offset, int limit) { + return selectByQueryImpl(dbSession, query, offset, limit); } - public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(DbSession session, String projectKey) { - return mapper(session).selectUuidsByKeyFromProjectKey(projectKey); + /** + * @throws IllegalArgumentException if parameter query#getComponentIds() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values + * @throws IllegalArgumentException if parameter query#getComponentKeys() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values + * @throws IllegalArgumentException if parameter query#getMainComponentUuids() has more than {@link org.sonar.db.DatabaseUtils#PARTITION_SIZE_FOR_ORACLE} values + */ + public int countByQuery(DbSession session, ComponentQuery query) { + return countByQueryImpl(session, query); } - public List<ComponentDto> selectProjectAndModulesFromProjectKey(DbSession session, String projectKey, boolean excludeDisabled) { - return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, Scopes.PROJECT, excludeDisabled); + private static List<ComponentDto> selectByQueryImpl(DbSession session, ComponentQuery query, int offset, int limit) { + if (query.hasEmptySetOfComponents()) { + return emptyList(); + } + checkThatNotTooManyComponents(query); + return mapper(session).selectByQuery(query, new RowBounds(offset, limit)); } - public int countEnabledModulesByBranchUuid(DbSession session, String branchUuid) { - return mapper(session).countEnabledModulesByBranchUuid(branchUuid); + private static int countByQueryImpl(DbSession session, ComponentQuery query) { + if (query.hasEmptySetOfComponents()) { + return 0; + } + checkThatNotTooManyComponents(query); + return mapper(session).countByQuery(query); } - public List<ComponentDto> selectEnabledModulesFromProjectKey(DbSession session, String projectKey) { - return selectProjectAndModulesFromProjectKey(session, projectKey, true); - } + /* + SELECT BY KEY + */ - public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) { - return executeLargeInputs(keys, mapper(session)::selectByKeys); + /** + * Return all components of a project (including disable ones) + */ + public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(DbSession session, String projectKey) { + return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, null, null); } - public List<ComponentDto> selectByKeysAndBranch(DbSession session, Collection<String> keys, String branch) { - return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, branch)); + public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKeyAndBranch(DbSession session, String projectKey, String branch) { + return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, branch, null); } - public List<ComponentDto> selectByKeysAndPullRequest(DbSession session, Collection<String> keys, String pullRequestId) { - return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranch(subKeys, pullRequestId)); + public List<KeyWithUuidDto> selectUuidsByKeyFromProjectKeyAndPullRequest(DbSession session, String projectKey, String pullrequest) { + return mapper(session).selectUuidsByKeyFromProjectKeyAndBranchOrPr(projectKey, null, pullrequest); } - public List<ComponentDto> selectByDbKeys(DbSession session, Collection<String> dbKeys) { - Map<String, List<String>> keyByBranchKey = new HashMap<>(); - Map<String, List<String>> keyByPrKey = new HashMap<>(); - List<String> mainBranchKeys = new LinkedList<>(); - - for (String dbKey : dbKeys) { - String branchKey = StringUtils.substringAfterLast(dbKey, ComponentDto.BRANCH_KEY_SEPARATOR); - if (!StringUtils.isEmpty(branchKey)) { - keyByBranchKey.computeIfAbsent(branchKey, b -> new LinkedList<>()) - .add(StringUtils.substringBeforeLast(dbKey, ComponentDto.BRANCH_KEY_SEPARATOR)); - continue; - } + /** + * If no branch or pull request is provided, returns components in the main branch + */ + public List<ComponentDto> selectProjectAndModulesFromProjectKey(DbSession session, String projectKey, boolean excludeDisabled, + @Nullable String branch, @Nullable String pullRequest) { + checkState(branch == null || pullRequest == null, "Can't set both branch and pull request"); + return mapper(session).selectComponentsFromProjectKeyAndScope(projectKey, Scopes.PROJECT, excludeDisabled, branch, pullRequest); + } - String prKey = StringUtils.substringAfterLast(dbKey, ComponentDto.PULL_REQUEST_SEPARATOR); - if (!StringUtils.isEmpty(prKey)) { - keyByPrKey.computeIfAbsent(prKey, b -> new LinkedList<>()) - .add(StringUtils.substringBeforeLast(dbKey, ComponentDto.PULL_REQUEST_SEPARATOR)); - continue; - } + /** + * If no branch or pull request is provided, returns components in the main branch + */ + public List<ComponentDto> selectEnabledModulesFromProjectKey(DbSession session, String projectKey, @Nullable String branch, @Nullable String pullRequest) { + return selectProjectAndModulesFromProjectKey(session, projectKey, true, branch, pullRequest); + } - mainBranchKeys.add(dbKey); - } + public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys) { + return selectByKeys(session, keys, null, null); + } - List<ComponentDto> components = new LinkedList<>(); - for (Map.Entry<String, List<String>> e : keyByBranchKey.entrySet()) { - components.addAll(selectByKeysAndBranch(session, e.getValue(), e.getKey())); - } - for (Map.Entry<String, List<String>> e : keyByPrKey.entrySet()) { - components.addAll(selectByKeysAndPullRequest(session, e.getValue(), e.getKey())); - } - components.addAll(selectByKeys(session, mainBranchKeys)); - return components; + /** + * If no branch or pull request is provided, returns components in the main branch + */ + public List<ComponentDto> selectByKeys(DbSession session, Collection<String> keys, @Nullable String branch, @Nullable String pullRequest) { + checkState(branch == null || pullRequest == null, "Can't set both branch and pull request"); + return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranchOrPr(subKeys, branch, pullRequest)); } /** @@ -258,11 +248,26 @@ public class ComponentDao implements Dao { return Optional.ofNullable(mapper(session).selectByKeyAndPrKey(key, pullRequestId)); } + /* + SELECT ALL + */ public List<UuidWithBranchUuidDto> selectAllViewsAndSubViews(DbSession session) { return mapper(session).selectUuidsForQualifiers(Qualifiers.APP, Qualifiers.VIEW, Qualifiers.SUBVIEW); } /** + * Returns all projects (Scope {@link Scopes#PROJECT} and qualifier + * {@link Qualifiers#PROJECT}) which are enabled. + * <p> + * Branches are not returned. + * <p> + * Used by Views. + */ + public List<ComponentDto> selectProjects(DbSession session) { + return mapper(session).selectProjects(); + } + + /** * Used by Governance */ public Set<String> selectViewKeysWithEnabledCopyOfProject(DbSession session, Set<String> projectUuids) { @@ -277,18 +282,6 @@ public class ComponentDao implements Dao { } /** - * Returns all projects (Scope {@link Scopes#PROJECT} and qualifier - * {@link Qualifiers#PROJECT}) which are enabled. - * <p> - * Branches are not returned. - * <p> - * Used by Views. - */ - public List<ComponentDto> selectProjects(DbSession session) { - return mapper(session).selectProjects(); - } - - /** * Selects all components that are relevant for indexing. The result is not returned (since it is usually too big), but handed over to the <code>handler</code> * * @param session the database session @@ -300,15 +293,6 @@ public class ComponentDao implements Dao { } /** - * Retrieves all components with a specific branch UUID, no other filtering is done by this method. - * <p> - * Used by Views plugin - */ - public List<ComponentDto> selectByBranchUuid(String branchUuid, DbSession dbSession) { - return mapper(dbSession).selectByBranchUuid(branchUuid); - } - - /** * Retrieve enabled components keys with given qualifiers * <p> * Used by Views plugin @@ -349,6 +333,25 @@ public class ComponentDao implements Dao { mapper(session).scrollAllFilesForFileMove(branchUuid, handler); } + public List<ProjectNclocDistributionDto> selectPrivateProjectsWithNcloc(DbSession dbSession) { + return mapper(dbSession).selectPrivateProjectsWithNcloc(); + } + + public boolean existAnyOfComponentsWithQualifiers(DbSession session, Collection<String> componentKeys, Set<String> qualifiers) { + if (!componentKeys.isEmpty()) { + List<Boolean> result = new LinkedList<>(); + return executeLargeInputs(componentKeys, input -> { + boolean groupNeedIssueSync = mapper(session).checkIfAnyOfComponentsWithQualifiers(input, qualifiers) > 0; + result.add(groupNeedIssueSync); + return result; + }).stream().anyMatch(b -> b); + } + return false; + } + + /* + INSERT / UPDATE + */ public void insert(DbSession session, ComponentDto item) { mapper(session).insert(item); if (!isBranchOrPullRequest(item)) { @@ -396,27 +399,18 @@ public class ComponentDao implements Dao { mapper(session).setPrivateForRootComponentUuid(branchUuid, isPrivate); } + /* + UTIL + */ + private static ComponentMapper mapper(DbSession session) { + return session.getMapper(ComponentMapper.class); + } + private static void checkThatNotTooManyComponents(ComponentQuery query) { checkThatNotTooManyConditions(query.getComponentKeys(), "Too many component keys in query"); checkThatNotTooManyConditions(query.getComponentUuids(), "Too many component UUIDs in query"); } - public List<ProjectNclocDistributionDto> selectPrivateProjectsWithNcloc(DbSession dbSession) { - return mapper(dbSession).selectPrivateProjectsWithNcloc(); - } - - public boolean existAnyOfComponentsWithQualifiers(DbSession session, Collection<String> componentKeys, Set<String> qualifiers) { - if (!componentKeys.isEmpty()) { - List<Boolean> result = new LinkedList<>(); - return executeLargeInputs(componentKeys, input -> { - boolean groupNeedIssueSync = mapper(session).checkIfAnyOfComponentsWithQualifiers(input, qualifiers) > 0; - result.add(groupNeedIssueSync); - return result; - }).stream().anyMatch(b -> b); - } - return false; - } - private static boolean isBranchOrPullRequest(ComponentDto item) { return item.getMainBranchProjectUuid() != null; } 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 d3303761465..ba308ad3ec2 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 @@ -46,8 +46,6 @@ public class ComponentDto { public static final String BRANCH_KEY_SEPARATOR = ":BRANCH:"; public static final String PULL_REQUEST_SEPARATOR = ":PULL_REQUEST:"; - private static final Splitter BRANCH_KEY_SPLITTER = Splitter.on(BRANCH_KEY_SEPARATOR); - public static final String UUID_PATH_SEPARATOR = "."; public static final String UUID_PATH_OF_ROOT = UUID_PATH_SEPARATOR; private static final Splitter UUID_PATH_SPLITTER = Splitter.on(UUID_PATH_SEPARATOR).omitEmptyStrings(); 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 ec86e389fe3..5e247061a92 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 @@ -32,9 +32,6 @@ import org.sonar.db.DbSession; import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.ComponentKeyNewValue; -import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR; -import static org.sonar.db.component.ComponentDto.generateBranchKey; - /** * Class used to rename the key of a project and its resources. * @@ -52,17 +49,17 @@ public class ComponentKeyUpdaterDao implements Dao { checkExistentKey(mapper, newKey); // must SELECT first everything - ResourceDto project = mapper.selectProjectByUuid(projectUuid); + ResourceDto project = mapper.selectComponentByUuid(projectUuid); String projectOldKey = project.getKey(); - List<ResourceDto> resources = mapper.selectProjectResources(projectUuid); + List<ResourceDto> resources = mapper.selectBranchResources(projectUuid); resources.add(project); // add branch components dbSession.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid).stream() .filter(branch -> !projectUuid.equals(branch.getUuid())) .forEach(branch -> { - resources.addAll(mapper.selectProjectResources(branch.getUuid())); - resources.add(mapper.selectProjectByUuid(branch.getUuid())); + resources.addAll(mapper.selectBranchResources(branch.getUuid())); + resources.add(mapper.selectComponentByUuid(branch.getUuid())); }); // and then proceed with the batch UPDATE at once @@ -70,29 +67,6 @@ public class ComponentKeyUpdaterDao implements Dao { }, dbSession); } - public void updateApplicationBranchKey(DbSession dbSession, String appBranchUuid, String appKey, String newBranchName) { - // TODO review - ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class); - - String newAppBranchKey = generateBranchKey(appKey, newBranchName); - checkExistentKey(mapper, newAppBranchKey); - - ResourceDto appBranch = mapper.selectProjectByUuid(appBranchUuid); - String appBranchOldKey = appBranch.getKey(); - appBranch.setKey(newAppBranchKey); - mapper.updateComponent(appBranch); - - auditPersister.componentKeyBranchUpdate(dbSession, new ComponentKeyNewValue(appBranchUuid, appBranchOldKey, newAppBranchKey), Qualifiers.APP); - - String oldAppBranchFragment = appBranchOldKey.replace(BRANCH_KEY_SEPARATOR, ""); - String newAppBranchFragment = appKey + newBranchName; - for (ResourceDto appBranchResource : mapper.selectProjectResources(appBranchUuid)) { - String newKey = computeNewKey(appBranchResource.getKey(), oldAppBranchFragment, newAppBranchFragment); - appBranchResource.setKey(newKey); - mapper.updateComponent(appBranchResource); - } - } - @VisibleForTesting static String computeNewKey(String key, String stringToReplace, String replacementString) { return key.replace(stringToReplace, replacementString); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java index 6a67af03dc2..f4c38fdf60c 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java @@ -26,9 +26,9 @@ public interface ComponentKeyUpdaterMapper { int countComponentsByKey(String key); - ResourceDto selectProjectByUuid(@Param("uuid") String uuid); + ResourceDto selectComponentByUuid(@Param("uuid") String uuid); - List<ResourceDto> selectProjectResources(@Param("rootUuid") String rootUuid); + List<ResourceDto> selectBranchResources(@Param("rootUuid") String rootUuid); void updateComponent(ResourceDto resource); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java index 98297278093..f669ff574df 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentMapper.java @@ -29,18 +29,11 @@ import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; public interface ComponentMapper { - - @CheckForNull - ComponentDto selectByKey(@Param("key") String key); - @CheckForNull ComponentDto selectByKeyCaseInsensitive(@Param("key") String key); @CheckForNull - ComponentDto selectByKeyAndBranchKey(@Param("key") String key, @Param("branch") String branch); - - @CheckForNull - ComponentDto selectByKeyAndPrKey(@Param("key") String key, @Param("pr") String pr); + ComponentDto selectByKeyAndBranchOrPr(@Param("key") String key, @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest); @CheckForNull ComponentDto selectByUuid(@Param("uuid") String uuid); @@ -50,9 +43,8 @@ public interface ComponentMapper { */ List<ComponentDto> selectSubProjectsByComponentUuids(@Param("uuids") Collection<String> uuids); - List<ComponentDto> selectByKeys(@Param("keys") Collection<String> keys); - - List<ComponentDto> selectByKeysAndBranch(@Param("keys") Collection<String> keys, @Param("branch") String branch); + List<ComponentDto> selectByKeysAndBranchOrPr(@Param("keys") Collection<String> keys, + @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest); List<ComponentDto> selectByUuids(@Param("uuids") Collection<String> uuids); @@ -109,12 +101,13 @@ public interface ComponentMapper { * @param scope scope of components to return. If null, all components are returned */ List<ComponentDto> selectComponentsFromProjectKeyAndScope(@Param("projectKey") String projectKey, @Nullable @Param("scope") String scope, - @Param(value = "excludeDisabled") boolean excludeDisabled); + @Param(value = "excludeDisabled") boolean excludeDisabled, @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest); /** * Return keys and UUIDs of all components belonging to a project */ - List<KeyWithUuidDto> selectUuidsByKeyFromProjectKey(@Param("projectKey") String projectKey); + List<KeyWithUuidDto> selectUuidsByKeyFromProjectKeyAndBranchOrPr(@Param("projectKey") String projectKey, + @Nullable @Param("branch") String branch, @Nullable @Param("pullRequest") String pullRequest); Set<String> selectViewKeysWithEnabledCopyOfProject(@Param("projectUuids") Collection<String> projectUuids); @@ -142,7 +135,7 @@ public interface ComponentMapper { void delete(String componentUuid); List<KeyWithUuidDto> selectComponentsFromPullRequestsTargetingCurrentBranchThatHaveOpenIssues(@Param("referenceBranchUuid") String referenceBranchUuid, - @Param("currentBranchUuid") String currentBranchUuid); + @Param("currentBranchUuid") String currentBranchUuid); List<KeyWithUuidDto> selectComponentsFromBranchesThatHaveOpenIssues(@Param("branchUuids") List<String> branchUuids); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java index ecf0f8520b8..ae54ec9fd17 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -42,6 +42,8 @@ import org.sonar.db.audit.AuditPersister; import org.sonar.db.audit.model.PropertyNewValue; import static com.google.common.base.Preconditions.checkArgument; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.apache.commons.lang.StringUtils.repeat; import static org.sonar.db.DatabaseUtils.executeLargeInputs; import static org.sonar.db.DatabaseUtils.executeLargeInputsIntoSet; @@ -67,7 +69,6 @@ public class PropertiesDao implements Dao { /** * Returns the logins of users who have subscribed to the given notification dispatcher with the given notification channel. * If a resource ID is passed, the search is made on users who have specifically subscribed for the given resource. - * * Note that {@link UserRole#USER} permission is not checked here, filter the results with * {@link org.sonar.db.permission.AuthorizationDao#keepAuthorizedLoginsOnProject} * @@ -151,14 +152,13 @@ public class PropertiesDao implements Dao { } } - // TODO distinguish branch from project - public List<PropertyDto> selectProjectProperties(DbSession session, String projectKey) { - return getMapper(session).selectProjectProperties(projectKey); + public List<PropertyDto> selectComponentProperties(DbSession session, String uuid) { + return getMapper(session).selectByComponentUuids(singletonList(uuid)); } - public List<PropertyDto> selectProjectProperties(String resourceKey) { + public List<PropertyDto> selectComponentProperties(String uuid) { try (DbSession session = mybatis.openSession(false)) { - return selectProjectProperties(session, resourceKey); + return selectComponentProperties(session, uuid); } } @@ -261,7 +261,6 @@ public class PropertiesDao implements Dao { * Delete either global, user, component or component per user properties. * <p>Behaves in exactly the same way as {@link #selectByQuery(PropertyQuery, DbSession)} but deletes rather than * selects</p> - * * Used by Governance. */ public int deleteByQuery(DbSession dbSession, PropertyQuery query) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index 2b4255ef3e0..e5975bd3458 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -262,7 +262,7 @@ class PurgeCommands { void deleteComponents(String rootUuid) { profiler.start("deleteComponents (projects)"); - purgeMapper.deleteComponentsByProjectUuid(rootUuid); + purgeMapper.deleteComponentsByBranchUuid(rootUuid); session.commit(); profiler.stop(); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index 1e8687178d4..c6139a76461 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -66,7 +66,7 @@ public interface PurgeMapper { void deletePropertiesByComponentUuids(@Param("componentUuids") List<String> componentUuids); - void deleteComponentsByProjectUuid(@Param("rootUuid") String rootUuid); + void deleteComponentsByBranchUuid(@Param("rootUuid") String rootUuid); void deleteComponentsByMainBranchProjectUuid(@Param("uuid") String uuid); diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml index 8112fb214dd..e004a66d79a 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentKeyUpdaterMapper.xml @@ -18,12 +18,12 @@ WHERE kee = #{key,jdbcType=VARCHAR} </select> - <select id="selectProjectByUuid" parameterType="String" resultMap="resourceResultMap"> + <select id="selectComponentByUuid" parameterType="String" resultMap="resourceResultMap"> select * from components where uuid = #{uuid,jdbcType=VARCHAR} </select> - <select id="selectProjectResources" parameterType="String" resultMap="resourceResultMap"> + <select id="selectBranchResources" parameterType="String" resultMap="resourceResultMap"> select * from components where root_uuid = #{rootUuid,jdbcType=VARCHAR} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml index c25cc05c20b..5f67411da9d 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -52,15 +52,28 @@ and pb.branch_type='BRANCH' </select> - <select id="selectByKeyAndPrKey" parameterType="String" resultType="Component"> + <select id="selectByKeyAndBranchOrPr" parameterType="String" resultType="Component"> select <include refid="componentColumns"/> from components p - inner join project_branches pb on pb.uuid = p.branch_uuid + <if test="branch != null || pullRequest != null"> + inner join project_branches pb on pb.uuid = p.branch_uuid + </if> where p.kee=#{key,jdbcType=VARCHAR} - and pb.kee=#{pr,jdbcType=VARCHAR} - and pb.branch_type='PULL_REQUEST' + <choose> + <when test="branch != null"> + AND pb.kee=#{branch,jdbcType=VARCHAR} + AND pb.branch_type = 'BRANCH' + </when> + <when test="pullRequest != null"> + AND pb.kee=#{pullRequest,jdbcType=VARCHAR} + AND pb.branch_type = 'PULL_REQUEST' + </when> + <otherwise> + AND p.main_branch_project_uuid is NULL + </otherwise> + </choose> </select> <select id="selectByUuid" parameterType="String" resultType="Component"> @@ -71,41 +84,32 @@ p.uuid=#{uuid,jdbcType=VARCHAR} </select> - <select id="selectByBranchUuid" parameterType="string" resultType="Component"> - select - <include refid="componentColumns"/> - from components root - inner join components p on p.branch_uuid=root.uuid - where - root.uuid=#{branchUuid,jdbcType=VARCHAR} - </select> - - <select id="selectByKeys" parameterType="String" resultType="Component"> - select - <include refid="componentColumns"/> - from components p - where - p.enabled=${_true} - and p.main_branch_project_uuid is null - and p.kee in - <foreach collection="keys" open="(" close=")" item="key" separator=","> - #{key,jdbcType=VARCHAR} - </foreach> - </select> - - <select id="selectByKeysAndBranch" parameterType="String" resultType="Component"> + <select id="selectByKeysAndBranchOrPr" parameterType="String" resultType="Component"> SELECT <include refid="componentColumns"/> FROM components p - INNER JOIN project_branches pb on pb.uuid = p.branch_uuid - <where> + <if test="branch != null || pullRequest != null"> + INNER JOIN project_branches pb on pb.uuid = p.branch_uuid + </if> + WHERE p.enabled=${_true} AND p.kee IN <foreach collection="keys" open="(" close=")" item="key" separator=","> #{key,jdbcType=VARCHAR} </foreach> - AND pb.kee=#{branch,jdbcType=VARCHAR} - </where> + <choose> + <when test="branch != null"> + AND pb.kee=#{branch,jdbcType=VARCHAR} + AND pb.branch_type = 'BRANCH' + </when> + <when test="pullRequest != null"> + AND pb.kee=#{pullRequest,jdbcType=VARCHAR} + AND pb.branch_type = 'PULL_REQUEST' + </when> + <otherwise> + AND p.main_branch_project_uuid IS NULL + </otherwise> + </choose> </select> <select id="selectByUuids" parameterType="String" resultType="Component"> @@ -477,6 +481,9 @@ <include refid="componentColumns"/> FROM components p INNER JOIN components root ON root.uuid=p.branch_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR} + <if test="branch != null || pullRequest != null"> + INNER JOIN project_branches pb ON pb.uuid=p.branch_uuid + </if> <where> <if test="excludeDisabled"> p.enabled = ${_true} @@ -484,9 +491,28 @@ <if test="scope != null"> AND p.scope=#{scope,jdbcType=VARCHAR} </if> + <choose> + <when test="branch != null"> + AND pb.kee=#{branch,jdbcType=VARCHAR} AND pb.branch_type = 'BRANCH' + </when> + <when test="pullRequest != null"> + AND pb.kee=#{pullRequest,jdbcType=VARCHAR} AND pb.branch_type = 'PULL_REQUEST' + </when> + <otherwise> + AND root.main_branch_project_uuid is null + </otherwise> + </choose> </where> </select> + <select id="selectByBranchUuid" parameterType="map" resultType="Component"> + SELECT + <include refid="componentColumns"/> + FROM components p + WHERE + p.branch_uuid = #{branchUuid,jdbcType=VARCHAR} + </select> + <select id="selectEnabledComponentsWithModuleUuidFromProjectKey" resultType="ComponentWithModuleUuid"> SELECT p.uuid as uuid, p.module_uuid as moduleUuid, p.path as path, p.scope as scope @@ -496,13 +522,31 @@ components root ON root.uuid=p.branch_uuid AND p.enabled = ${_true} AND root.kee=#{projectKey,jdbcType=VARCHAR} </select> - <select id="selectUuidsByKeyFromProjectKey" parameterType="string" resultType="KeyWithUuid"> + <select id="selectUuidsByKeyFromProjectKeyAndBranchOrPr" parameterType="string" resultType="KeyWithUuid"> SELECT p.kee, p.uuid FROM components p INNER JOIN components root ON root.uuid=p.branch_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR} + <if test="branch != null || pullRequest != null"> + INNER JOIN project_branches pb ON pb.uuid = root.uuid + </if> + + <choose> + <when test="branch != null"> + AND pb.kee = #{branch,jdbcType=VARCHAR} + AND pb.branch_type = 'BRANCH' + </when> + <when test="pullRequest != null"> + AND pb.kee=#{pullRequest,jdbcType=VARCHAR} + AND pb.branch_type = 'PULL_REQUEST' + </when> + <otherwise> + AND root.main_branch_project_uuid is NULL + </otherwise> + </choose> + </select> <select id="scrollForIndexing" parameterType="map" resultType="Component" fetchSize="${_scrollFetchSize}" resultSetType="FORWARD_ONLY"> diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index db14d3c6646..94b0f1f028d 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -217,7 +217,7 @@ </foreach> </delete> - <delete id="deleteComponentsByProjectUuid" parameterType="map"> + <delete id="deleteComponentsByBranchUuid" parameterType="map"> delete from components where branch_uuid = #{rootUuid,jdbcType=VARCHAR} diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java index 8104002008b..12d3bcd450a 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java @@ -200,8 +200,9 @@ public class ComponentDaoTest { } @Test - public void selectByKey() { + public void select_by_key() { ComponentDto project = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project); ComponentDto directory = db.components().insertComponent(newDirectory(project, "src")); ComponentDto file = db.components().insertComponent(newFileDto(project, directory) .setKey("org.struts:struts-core:src/org/struts/RequestContext.java") @@ -210,6 +211,7 @@ public class ComponentDaoTest { .setLanguage("java") .setPath("src/RequestContext.java")); + assertThat(underTest.selectByKey(dbSession, project.getKey())).isPresent(); Optional<ComponentDto> optional = underTest.selectByKey(dbSession, file.getKey()); ComponentDto result = optional.get(); @@ -227,7 +229,7 @@ public class ComponentDaoTest { } @Test - public void selectByKeyAndBranch() { + public void select_by_key_and_branch() { ComponentDto project = db.components().insertPublicProject(); ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch").setBranchType(BRANCH)); ComponentDto file = db.components().insertComponent(newFileDto(branch)); @@ -240,7 +242,7 @@ public class ComponentDaoTest { } @Test - public void selectByKeyAndPullRequest() { + public void select_by_key_and_pull_request() { ComponentDto project = db.components().insertPublicProject(); ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); ComponentDto pullRequest = db.components().insertProjectBranch(project, b -> b.setKey("my_PR").setBranchType(PULL_REQUEST)); @@ -257,18 +259,10 @@ public class ComponentDaoTest { } @Test - public void selectOrFailByKey_fails_when_component_not_found() { - db.components().insertPrivateProject(); - - assertThatThrownBy(() -> underTest.selectOrFailByKey(dbSession, "unknown")) - .isInstanceOf(RowNotFoundException.class); - } - - @Test public void get_by_key_on_disabled_component() { ComponentDto project = db.components().insertPrivateProject(p -> p.setEnabled(false)); - ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getKey()); + ComponentDto result = underTest.selectByKey(dbSession, project.getKey()).get(); assertThat(result.isEnabled()).isFalse(); } @@ -277,7 +271,7 @@ public class ComponentDaoTest { public void get_by_key_on_a_root_project() { ComponentDto project = db.components().insertPrivateProject(); - ComponentDto result = underTest.selectOrFailByKey(dbSession, project.getKey()); + ComponentDto result = underTest.selectByKey(dbSession, project.getKey()).get(); assertThat(result.getKey()).isEqualTo(project.getKey()); assertThat(result.uuid()).isEqualTo(project.uuid()); @@ -287,8 +281,9 @@ public class ComponentDaoTest { } @Test - public void get_by_keys() { + public void select_by_keys() { ComponentDto project1 = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project1); ComponentDto project2 = db.components().insertPrivateProject(); List<ComponentDto> results = underTest.selectByKeys(dbSession, asList(project1.getKey(), project2.getKey())); @@ -299,26 +294,52 @@ public class ComponentDaoTest { tuple(project1.uuid(), project1.getKey()), tuple(project2.uuid(), project2.getKey())); - assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"))).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"), null, null)).isEmpty(); + } + + @Test + public void select_by_keys_throws_ISE_if_both_branch_and_pr_are_passed() { + assertThatThrownBy(() -> underTest.selectByKeys(db.getSession(), List.of("key"), "branch", "pr")) + .isInstanceOf(IllegalStateException.class); } @Test - public void selectByKeysAndBranch() { + public void select_by_keys_with_branch() { + String branchKey = "my_branch"; ComponentDto project = db.components().insertPublicProject(); - ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch")); + ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchKey)); ComponentDto file1 = db.components().insertComponent(newFileDto(branch)); ComponentDto file2 = db.components().insertComponent(newFileDto(branch)); ComponentDto anotherBranch = db.components().insertProjectBranch(project, b -> b.setKey("another_branch")); ComponentDto fileOnAnotherBranch = db.components().insertComponent(newFileDto(anotherBranch)); - assertThat(underTest.selectByKeysAndBranch(dbSession, asList(branch.getKey(), file1.getKey(), file2.getKey()), "my_branch")).extracting(ComponentDto::uuid) + assertThat(underTest.selectByKeys(dbSession, asList(branch.getKey(), file1.getKey(), file2.getKey()), branchKey, null)).extracting(ComponentDto::uuid) .containsExactlyInAnyOrder(branch.uuid(), file1.uuid(), file2.uuid()); - assertThat(underTest.selectByKeysAndBranch(dbSession, asList(file1.getKey(), file2.getKey(), fileOnAnotherBranch.getKey()), "my_branch")).extracting(ComponentDto::uuid) + assertThat(underTest.selectByKeys(dbSession, asList(file1.getKey(), file2.getKey(), fileOnAnotherBranch.getKey()), branchKey, null)).extracting(ComponentDto::uuid) .containsExactlyInAnyOrder(file1.uuid(), file2.uuid()); - assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(fileOnAnotherBranch.getKey()), "my_branch")).isEmpty(); - assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(file1.getKey()), "unknown")).isEmpty(); - assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList("unknown"), "my_branch")).isEmpty(); - assertThat(underTest.selectByKeysAndBranch(dbSession, singletonList(branch.getKey()), "my_branch")).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(branch.uuid()); + assertThat(underTest.selectByKeys(dbSession, singletonList(fileOnAnotherBranch.getKey()), branchKey, null)).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList(file1.getKey()), "unknown", null)).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"), branchKey, null)).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList(branch.getKey()), branchKey, null)).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(branch.uuid()); + } + + @Test + public void select_by_keys_with_pr() { + String prKey = "my_branch"; + ComponentDto project = db.components().insertPublicProject(); + ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey(prKey).setBranchType(PULL_REQUEST)); + ComponentDto file1 = db.components().insertComponent(newFileDto(pr)); + ComponentDto anotherBranch = db.components().insertProjectBranch(project, b -> b.setKey(prKey)); + ComponentDto fileOnAnotherBranch = db.components().insertComponent(newFileDto(anotherBranch)); + + assertThat(underTest.selectByKeys(dbSession, asList(pr.getKey(), file1.getKey()), null, prKey)).extracting(ComponentDto::uuid) + .containsExactlyInAnyOrder(pr.uuid(), file1.uuid()); + assertThat(underTest.selectByKeys(dbSession, asList(file1.getKey(), fileOnAnotherBranch.getKey()), null, prKey)).extracting(ComponentDto::uuid) + .containsExactlyInAnyOrder(file1.uuid()); + assertThat(underTest.selectByKeys(dbSession, singletonList(fileOnAnotherBranch.getKey()), null, prKey)).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList(file1.getKey()), null, "unknown")).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList("unknown"), null, prKey)).isEmpty(); + assertThat(underTest.selectByKeys(dbSession, singletonList(pr.getKey()), null, prKey)).extracting(ComponentDto::uuid).containsExactlyInAnyOrder(pr.uuid()); } @Test @@ -598,7 +619,7 @@ public class ComponentDaoTest { } @Test - public void select_all_components_from_project() { + public void select_by_branch_uuid() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false)); ComponentDto module = db.components().insertComponent(newModuleDto(project)); @@ -611,17 +632,18 @@ public class ComponentDaoTest { ComponentDto removedFile = db.components().insertComponent(newFileDto(subModule, directory).setEnabled(false)); // Removed components are included - assertThat(underTest.selectAllComponentsFromProjectKey(dbSession, project.getKey())) + assertThat(underTest.selectByBranchUuid(project.uuid(), dbSession)) .extracting(ComponentDto::getKey) .containsExactlyInAnyOrder(project.getKey(), module.getKey(), removedModule.getKey(), subModule.getKey(), removedSubModule.getKey(), directory.getKey(), removedDirectory.getKey(), file.getKey(), removedFile.getKey()); - assertThat(underTest.selectAllComponentsFromProjectKey(dbSession, "UNKNOWN")).isEmpty(); + assertThat(underTest.selectByBranchUuid("UNKNOWN", dbSession)).isEmpty(); } @Test public void select_uuids_by_key_from_project() { ComponentDto project = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project); ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false)); ComponentDto module = db.components().insertComponent(newModuleDto(project)); ComponentDto removedModule = db.components().insertComponent(newModuleDto(project).setEnabled(false)); @@ -648,6 +670,52 @@ public class ComponentDaoTest { } @Test + public void select_uuids_by_key_from_project_and_branch() { + String branchKey = "branch1"; + ComponentDto project = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchKey)); + ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey(branchKey).setBranchType(PULL_REQUEST)); + ComponentDto module = db.components().insertComponent(newModuleDto(branch)); + ComponentDto subModule = db.components().insertComponent(newModuleDto(module)); + ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src")); + ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory)); + ComponentDto projectFile = db.components().insertComponent(newFileDto(project, directory)); + + Map<String, String> uuidsByKey = underTest.selectUuidsByKeyFromProjectKeyAndBranch(dbSession, project.getKey(), branchKey) + .stream().collect(Collectors.toMap(KeyWithUuidDto::key, KeyWithUuidDto::uuid)); + + assertThat(uuidsByKey).containsOnly( + entry(branch.getKey(), branch.uuid()), + entry(module.getKey(), module.uuid()), + entry(subModule.getKey(), subModule.uuid()), + entry(directory.getKey(), directory.uuid()), + entry(file.getKey(), file.uuid())); + } + + @Test + public void select_uuids_by_key_from_project_and_pr() { + String prKey = "pr1"; + ComponentDto project = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(prKey).setBranchType(PULL_REQUEST)); + ComponentDto pr = db.components().insertProjectBranch(project, b -> b.setKey(prKey).setBranchType(BRANCH)); + ComponentDto module = db.components().insertComponent(newModuleDto(branch)); + ComponentDto subModule = db.components().insertComponent(newModuleDto(module)); + ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src")); + ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory)); + ComponentDto projectFile = db.components().insertComponent(newFileDto(project, directory)); + + Map<String, String> uuidsByKey = underTest.selectUuidsByKeyFromProjectKeyAndPullRequest(dbSession, project.getKey(), prKey) + .stream().collect(Collectors.toMap(KeyWithUuidDto::key, KeyWithUuidDto::uuid)); + + assertThat(uuidsByKey).containsOnly( + entry(branch.getKey(), branch.uuid()), + entry(module.getKey(), module.uuid()), + entry(subModule.getKey(), subModule.uuid()), + entry(directory.getKey(), directory.uuid()), + entry(file.getKey(), file.uuid())); + } + + @Test public void select_enabled_modules_from_project() { ComponentDto project = db.components().insertPrivateProject(); ComponentDto removedProject = db.components().insertPrivateProject(p -> p.setEnabled(false)); @@ -661,11 +729,41 @@ public class ComponentDaoTest { ComponentDto removedFile = db.components().insertComponent(newFileDto(subModule, directory).setEnabled(false)); // Removed modules are not included - assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey())) + assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey(), null, null)) .extracting(ComponentDto::getKey) .containsExactlyInAnyOrder(project.getKey(), module.getKey(), subModule.getKey()); - assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, "UNKNOWN")).isEmpty(); + assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, "UNKNOWN", null, null)).isEmpty(); + } + + @Test + public void select_enabled_modules_from_branch() { + ComponentDto project = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("branch1")); + ComponentDto module = db.components().insertComponent(newModuleDto(branch)); + ComponentDto subModule = db.components().insertComponent(newModuleDto(module)); + ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src")); + ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory)); + + // Removed modules are not included + assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey(), "branch1", null)) + .extracting(ComponentDto::getKey) + .containsExactlyInAnyOrder(project.getKey(), module.getKey(), subModule.getKey()); + } + + @Test + public void select_enabled_modules_from_pr() { + ComponentDto project = db.components().insertPrivateProject(); + ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(PULL_REQUEST).setKey("pr1")); + ComponentDto module = db.components().insertComponent(newModuleDto(branch)); + ComponentDto subModule = db.components().insertComponent(newModuleDto(module)); + ComponentDto directory = db.components().insertComponent(newDirectory(subModule, "src")); + ComponentDto file = db.components().insertComponent(newFileDto(subModule, directory)); + + // Removed modules are not included + assertThat(underTest.selectEnabledModulesFromProjectKey(dbSession, project.getKey(), null, "pr1")) + .extracting(ComponentDto::getKey) + .containsExactlyInAnyOrder(project.getKey(), module.getKey(), subModule.getKey()); } @Test @@ -1948,7 +2046,7 @@ public class ComponentDaoTest { ComponentDto project = db.components().insertPublicProject(); BranchDto branch = newBranchDto(project); ComponentDto branchComponent = newBranchComponent(project, branch); - + underTestWithAuditPersister.insert(dbSession, branchComponent); verifyNoInteractions(auditPersister); @@ -1981,8 +2079,8 @@ public class ComponentDaoTest { private static Set<String> shuffleWithNonExistentUuids(String... uuids) { return Stream.concat( - IntStream.range(0, 1 + new Random().nextInt(5)).mapToObj(i -> randomAlphabetic(9)), - Arrays.stream(uuids)) + IntStream.range(0, 1 + new Random().nextInt(5)).mapToObj(i -> randomAlphabetic(9)), + Arrays.stream(uuids)) .collect(toSet()); } 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 963b007a7e8..56da8d37e29 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 @@ -21,11 +21,9 @@ package org.sonar.db.component; import com.google.common.base.Strings; import java.util.List; -import java.util.Map; import org.assertj.core.groups.Tuple; import org.junit.Rule; import org.junit.Test; -import org.sonar.api.resources.Qualifiers; import org.sonar.api.utils.System2; import org.sonar.db.DbClient; import org.sonar.db.DbSession; @@ -42,8 +40,6 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.sonar.db.component.BranchType.PULL_REQUEST; -import static org.sonar.db.component.ComponentDto.BRANCH_KEY_SEPARATOR; -import static org.sonar.db.component.ComponentDto.generateBranchKey; import static org.sonar.db.component.ComponentKeyUpdaterDao.computeNewKey; import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; @@ -95,7 +91,7 @@ public class ComponentKeyUpdaterDaoTest { underTest.updateKey(dbSession, "A", "your_project"); dbSession.commit(); - List<ComponentDto> result = dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, "your_project"); + List<ComponentDto> result = dbClient.componentDao().selectByBranchUuid("A", dbSession); assertThat(result) .hasSize(5) .extracting(ComponentDto::getKey) @@ -103,59 +99,6 @@ public class ComponentKeyUpdaterDaoTest { } @Test - public void update_application_branch_key() { - ComponentDto app = db.components().insertPublicProject(); - ComponentDto appBranch = db.components().insertProjectBranch(app); - ComponentDto appBranchProj1 = appBranch.copy() - .setKey(appBranch.getKey().replace(BRANCH_KEY_SEPARATOR, "") + "appBranchProj1").setUuid("appBranchProj1").setScope(Qualifiers.FILE); - ComponentDto appBranchProj2 = appBranch.copy() - .setKey(appBranch.getKey().replace(BRANCH_KEY_SEPARATOR, "") + "appBranchProj2").setUuid("appBranchProj2").setScope(Qualifiers.FILE); - db.components().insertComponent(appBranchProj1); - db.components().insertComponent(appBranchProj2); - int branchComponentCount = 3; - - String oldBranchKey = appBranch.getKey(); - assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).hasSize(branchComponentCount); - - String newBranchName = "newKey"; - String newAppBranchKey = ComponentDto.generateBranchKey(app.getKey(), newBranchName); - String newAppBranchFragment = app.getKey() + newBranchName; - underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getKey(), newBranchName); - - assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, oldBranchKey)).isEmpty(); - - assertThat(dbClient.componentDao().selectAllComponentsFromProjectKey(dbSession, newAppBranchKey)).hasSize(branchComponentCount); - - List<Map<String, Object>> result = db.select(dbSession, String.format("select kee from components where root_uuid = '%s' and scope != 'PRJ'", appBranch.uuid())); - - assertThat(result).hasSize(2); - result.forEach(map -> map.values().forEach(k -> assertThat(k.toString()).startsWith(newAppBranchFragment))); - } - - @Test - public void update_application_branch_key_will_fail_if_newKey_exist() { - ComponentDto app = db.components().insertPublicProject(); - ComponentDto appBranch = db.components().insertProjectBranch(app); - db.components().insertProjectBranch(app, b -> b.setKey("newName")); - - assertThatThrownBy(() -> underTest.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getKey(), "newName")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage(String.format("Impossible to update key: a component with key \"%s\" already exists.", generateBranchKey(app.getKey(), "newName"))); - } - - @Test - public void updateApplicationBranchKey_callsAuditPersister() { - ComponentDto app = db.components().insertPublicProject(); - ComponentDto appBranch = db.components().insertProjectBranch(app); - db.components().insertProjectBranch(app, b -> b.setKey("newName")); - - underTestWithAuditPersister.updateApplicationBranchKey(dbSession, appBranch.uuid(), app.getKey(), "newName2"); - - verify(auditPersister, times(1)) - .componentKeyBranchUpdate(any(DbSession.class), any(ComponentKeyNewValue.class), anyString()); - } - - @Test public void updateKey_updates_branches_too() { ComponentDto project = db.components().insertPublicProject(); String branchName = randomAlphanumeric(248); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java index 40cf19f892a..f71e2089de1 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/property/PropertiesDaoTest.java @@ -155,7 +155,7 @@ public class PropertiesDaoTest { user1.getLogin(), projectKey, projectName); // global subscription insertProperty("notification.DispatcherWithGlobalAndProjectSubscribers.Email", "true", null, user2.getUuid(), - user2.getLogin(), null,null); + user2.getLogin(), null, null); // Nobody is subscribed assertThat(underTest.hasProjectNotificationSubscribersForDispatchers(projectUuid, singletonList("NotSexyDispatcher"))) @@ -459,8 +459,8 @@ public class PropertiesDaoTest { @Test public void selectGlobalProperties() { // global - insertProperty("global.one", "one", null, null, null, null,null); - insertProperty("global.two", "two", null, null, null, null,null); + insertProperty("global.one", "one", null, null, null, null, null); + insertProperty("global.two", "two", null, null, null, null, null); List<PropertyDto> properties = underTest.selectGlobalProperties(); assertThat(properties.size()) @@ -492,7 +492,7 @@ public class PropertiesDaoTest { @Test public void selectGlobalProperty() { // global - insertProperty("global.one", "one", null, null, null, null,null); + insertProperty("global.one", "one", null, null, null, null, null); insertProperty("global.two", "two", null, null, null, null, null); // project insertProperty("project.one", "one", "uuid10", null, null, "component", "component"); @@ -519,35 +519,12 @@ public class PropertiesDaoTest { } @Test - public void selectProjectProperties() { - ComponentDto projectDto = insertPrivateProject("A"); - String projectUuid = projectDto.uuid(); - // global - insertProperty("global.one", "one", null, null, null, null, null); - insertProperty("global.two", "two", null, null, null, null, null); - // project - insertProperty("project.one", "Pone", projectUuid, null, null, projectDto.getKey(), projectDto.name()); - insertProperty("project.two", "Ptwo", projectUuid, null, null, projectDto.getKey(), projectDto.name()); - - List<PropertyDto> dtos = underTest.selectProjectProperties(projectDto.getKey()); - assertThat(dtos) - .hasSize(2); - assertThat(findByKey(dtos, "project.one")) - .extracting(PropertyDto::getKey, PropertyDto::getComponentUuid, PropertyDto::getValue) - .containsExactly("project.one", projectUuid, "Pone"); - - assertThat(findByKey(dtos, "project.two")) - .extracting(PropertyDto::getKey, PropertyDto::getComponentUuid, PropertyDto::getValue) - .containsExactly("project.two", projectUuid, "Ptwo"); - } - - @Test @UseDataProvider("allValuesForSelect") public void selectProjectProperties_supports_all_values(String dbValue, String expected) { ComponentDto projectDto = insertPrivateProject("A"); insertProperty("project.one", dbValue, projectDto.uuid(), null, null, projectDto.getKey(), projectDto.name()); - List<PropertyDto> dtos = underTest.selectProjectProperties(projectDto.getKey()); + List<PropertyDto> dtos = underTest.selectComponentProperties(projectDto.uuid()); assertThat(dtos).hasSize(1); assertThat(dtos.iterator().next()) @@ -654,6 +631,8 @@ public class PropertiesDaoTest { assertThat(underTest.selectPropertiesByComponentUuids(session, newHashSet(project.uuid()))) .extracting("key", "componentUuid").containsOnly(tuple(key, project.uuid())); + assertThat(underTest.selectComponentProperties(session, (project.uuid()))) + .extracting("key", "componentUuid").containsOnly(tuple(key, project.uuid())); assertThat(underTest.selectPropertiesByComponentUuids(session, newHashSet(project.uuid(), project2.uuid()))) .extracting("key", "componentUuid").containsOnly( tuple(key, project.uuid()), @@ -671,7 +650,7 @@ public class PropertiesDaoTest { String key = "key"; String anotherKey = "anotherKey"; - insertProperties(null, null,null, newGlobalPropertyDto().setKey(key)); + insertProperties(null, null, null, newGlobalPropertyDto().setKey(key)); insertProperties(null, project.getKey(), project.name(), newComponentPropertyDto(project).setKey(key)); insertProperties(null, project2.getKey(), project2.name(), newComponentPropertyDto(project2).setKey(key), newComponentPropertyDto(project2).setKey(anotherKey)); @@ -1250,7 +1229,7 @@ public class PropertiesDaoTest { @Test public void rename_to_same_key_has_no_effect() { - String uuid = insertProperty("foo", "bar", null, null, null, null,null); + String uuid = insertProperty("foo", "bar", null, null, null, null, null); assertThatPropertiesRowByUuid(uuid) .hasCreatedAt(INITIAL_DATE); diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java index 2d7c7987556..8681d7b8391 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java @@ -94,6 +94,11 @@ public class ComponentDbTester { return insertComponentAndBranchAndProject(ComponentTesting.newPublicProjectDto(uuid), false); } + public ComponentDto insertPublicProject(String uuid, Consumer<ComponentDto> dtoPopulator) { + return insertComponentAndBranchAndProject(ComponentTesting.newPublicProjectDto(uuid), false, defaults(), dtoPopulator); + } + + public ComponentDto insertPublicProject(ComponentDto componentDto) { return insertComponentAndBranchAndProject(componentDto, false); } diff --git a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/property/PropertyDbTester.java b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/property/PropertyDbTester.java index 76f9af0eee1..98f07e9ddb6 100644 --- a/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/property/PropertyDbTester.java +++ b/server/sonar-db-dao/src/testFixtures/java/org/sonar/db/property/PropertyDbTester.java @@ -31,6 +31,7 @@ import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.db.property.PropertyTesting.newComponentPropertyDto; import static org.sonar.db.property.PropertyTesting.newGlobalPropertyDto; @@ -55,8 +56,7 @@ public class PropertyDbTester { } public void insertProperties(@Nullable String userLogin, @Nullable String projectKey, - @Nullable String projectName, @Nullable String qualifier, - PropertyDto... properties) { + @Nullable String projectName, @Nullable String qualifier, PropertyDto... properties) { insertProperties(asList(properties), userLogin, projectKey, projectName, qualifier); } @@ -68,6 +68,14 @@ public class PropertyDbTester { dbSession.commit(); } + public void insertProperty(String propKey, String propValue, @Nullable String componentUuid) { + insertProperties(singletonList(new PropertyDto() + .setKey(propKey) + .setValue(propValue) + .setComponentUuid(componentUuid)), + null, null, null, null); + } + public void insertPropertySet(String settingBaseKey, @Nullable ComponentDto componentDto, Map<String, String>... fieldValues) { int index = 1; List<PropertyDto> propertyDtos = new ArrayList<>(); @@ -96,22 +104,6 @@ public class PropertyDbTester { insertProperties(propertyDtos, null, componentKey, componentName, qualififer); } - public PropertyDbTester verifyInternal(String key, @Nullable String expectedValue) { - Optional<String> value = dbClient.internalPropertiesDao().selectByKey(dbSession, key); - if (expectedValue == null) { - assertThat(value).isEmpty(); - } else { - assertThat(value).hasValue(expectedValue); - } - return this; - } - - public PropertyDbTester insertInternal(String key, String value) { - dbClient.internalPropertiesDao().save(dbSession, key, value); - dbSession.commit(); - return this; - } - public Optional<PropertyDto> findFirstUserProperty(String userUuid, String key) { PropertyQuery query = new PropertyQuery.Builder() .setUserUuid(userUuid) |