aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao/src
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2021-10-18 16:21:38 -0500
committersonartech <sonartech@sonarsource.com>2021-11-09 20:03:15 +0000
commit8f6a40a2c3e066865f64955636683ac482b50526 (patch)
treeca88ad23a516b56a786d15f80ae88654cb3d96db /server/sonar-db-dao/src
parent6bd7a4fd3a9fcbed5367add7ba9f616531ced342 (diff)
downloadsonarqube-8f6a40a2c3e066865f64955636683ac482b50526.tar.gz
sonarqube-8f6a40a2c3e066865f64955636683ac482b50526.zip
SONAR-15498 DB schema and WS supports project branches selection in portfolios
Diffstat (limited to 'server/sonar-db-dao/src')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java1
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java72
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDto.java10
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java16
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioProjectDto.java31
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml149
-rw-r--r--server/sonar-db-dao/src/schema/schema-sq.ddl11
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java130
-rw-r--r--server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentDbTester.java7
9 files changed, 315 insertions, 112 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
index 6ef83f82a46..298be87c731 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java
@@ -203,7 +203,6 @@ public class MyBatis implements Startable {
confBuilder.loadAlias("Portfolio", PortfolioDto.class);
confBuilder.loadAlias("PortfolioProject", PortfolioProjectDto.class);
confBuilder.loadAlias("PortfolioReference", PortfolioReferenceDto.class);
-
confBuilder.loadAlias("PrIssue", PrIssueDto.class);
confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class);
confBuilder.loadAlias("Project", ProjectDto.class);
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java
index 5a70462b650..4682d92edfd 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDao.java
@@ -19,12 +19,9 @@
*/
package org.sonar.db.portfolio;
-import java.util.Collection;
import java.util.List;
-import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collectors;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.System2;
import org.sonar.core.util.UuidFactory;
@@ -32,9 +29,9 @@ import org.sonar.db.Dao;
import org.sonar.db.DbSession;
import org.sonar.db.audit.AuditPersister;
import org.sonar.db.audit.model.ComponentNewValue;
-import org.sonar.db.project.ProjectDto;
import static com.google.common.base.Preconditions.checkArgument;
+import static java.lang.String.format;
import static java.util.Collections.emptyList;
import static java.util.Collections.singleton;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
@@ -50,6 +47,9 @@ public class PortfolioDao implements Dao {
this.auditPersister = auditPersister;
}
+ /*
+ * Select portfolios
+ */
public List<PortfolioDto> selectAllRoots(DbSession dbSession) {
return mapper(dbSession).selectAllRoots();
}
@@ -81,6 +81,9 @@ public class PortfolioDao implements Dao {
return mapper(dbSession).selectByUuids(uuids);
}
+ /*
+ * Modify portfolios
+ */
public void insert(DbSession dbSession, PortfolioDto portfolio) {
checkArgument(portfolio.isRoot() == (portfolio.getUuid().equals(portfolio.getRootUuid())));
mapper(dbSession).insert(portfolio);
@@ -106,20 +109,9 @@ public class PortfolioDao implements Dao {
auditPersister.updateComponent(dbSession, toComponentNewValue(portfolio));
}
- private static ComponentNewValue toComponentNewValue(PortfolioDto portfolio) {
- return new ComponentNewValue(portfolio.getUuid(), portfolio.getName(), portfolio.getKey(), portfolio.isPrivate(),
- portfolio.getDescription(), qualifier(portfolio));
- }
-
- private static String qualifier(PortfolioDto portfolioDto) {
- return portfolioDto.isRoot() ? Qualifiers.VIEW : Qualifiers.SUBVIEW;
- }
-
- public Map<String, String> selectKeysByUuids(DbSession dbSession, Collection<String> uuids) {
- return executeLargeInputs(uuids, uuids1 -> mapper(dbSession).selectByUuids(uuids1)).stream()
- .collect(Collectors.toMap(PortfolioDto::getUuid, PortfolioDto::getKey));
- }
-
+ /*
+ * Portfolio references
+ */
public void addReference(DbSession dbSession, String portfolioUuid, String referenceUuid) {
mapper(dbSession).insertReference(new PortfolioReferenceDto()
.setUuid(uuidFactory.create())
@@ -168,8 +160,11 @@ public class PortfolioDao implements Dao {
return mapper(dbSession).selectReference(portfolioUuid, referenceKey);
}
- public List<ProjectDto> selectProjects(DbSession dbSession, String portfolioUuid) {
- return mapper(dbSession).selectProjects(portfolioUuid);
+ /*
+ * Manual selection of projects
+ */
+ public List<PortfolioProjectDto> selectPortfolioProjects(DbSession dbSession, String portfolioUuid) {
+ return mapper(dbSession).selectPortfolioProjects(portfolioUuid);
}
public List<PortfolioProjectDto> selectAllProjectsInHierarchy(DbSession dbSession, String rootUuid) {
@@ -180,12 +175,15 @@ public class PortfolioDao implements Dao {
return mapper(dbSession).selectAllPortfolioProjects();
}
- public void addProject(DbSession dbSession, String portfolioUuid, String projectUuid) {
- mapper(dbSession).insertProject(new PortfolioProjectDto()
- .setUuid(uuidFactory.create())
- .setPortfolioUuid(portfolioUuid)
- .setProjectUuid(projectUuid)
- .setCreatedAt(system2.now()));
+ public PortfolioProjectDto selectPortfolioProjectOrFail(DbSession dbSession, String portfolioUuid, String projectUuid) {
+ return Optional.ofNullable(mapper(dbSession).selectPortfolioProject(portfolioUuid, projectUuid)).orElseThrow(() ->
+ new IllegalArgumentException(format("Project '%s' not selected in portfolio '%s'", projectUuid, portfolioUuid)));
+ }
+
+ public String addProject(DbSession dbSession, String portfolioUuid, String projectUuid) {
+ String uuid = uuidFactory.create();
+ mapper(dbSession).insertProject(uuid, portfolioUuid, projectUuid, system2.now());
+ return uuid;
}
public void deleteProjects(DbSession dbSession, String portfolioUuid) {
@@ -200,8 +198,30 @@ public class PortfolioDao implements Dao {
mapper(dbSession).deleteAllProjects();
}
+ public Set<String> selectBranches(DbSession dbSession, String portfolioProjectUuid) {
+ return mapper(dbSession).selectBranches(portfolioProjectUuid);
+ }
+
+ public void addBranch(DbSession dbSession, String portfolioProjectUuid, String branchKey) {
+ mapper(dbSession).insertBranch(uuidFactory.create(), portfolioProjectUuid, branchKey, system2.now());
+ }
+
+ public void deleteBranch(DbSession dbSession, String portfolioUuid, String projectUuid, String branchKey) {
+ mapper(dbSession).deleteBranch(portfolioUuid, projectUuid, branchKey);
+ }
+
+ /*
+ * Utils
+ */
private static PortfolioMapper mapper(DbSession session) {
return session.getMapper(PortfolioMapper.class);
}
+ private static ComponentNewValue toComponentNewValue(PortfolioDto portfolio) {
+ return new ComponentNewValue(portfolio.getUuid(), portfolio.isPrivate(), portfolio.getName(), portfolio.getKey(), portfolio.getDescription(), qualifier(portfolio));
+ }
+
+ private static String qualifier(PortfolioDto portfolioDto) {
+ return portfolioDto.isRoot() ? Qualifiers.VIEW : Qualifiers.SUBVIEW;
+ }
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDto.java
index 6b6c790c9b8..48195cc50ea 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioDto.java
@@ -33,6 +33,7 @@ public class PortfolioDto {
private String name;
private String description;
private boolean isPrivate = false;
+ private String branchName;
private String rootUuid;
private String parentUuid;
@@ -69,6 +70,15 @@ public class PortfolioDto {
return this;
}
+ @CheckForNull
+ public String getBranchName() {
+ return branchName;
+ }
+
+ public void setBranchName(@Nullable String branchName) {
+ this.branchName = branchName;
+ }
+
public String getSelectionMode() {
return selectionMode;
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java
index c337e8a1b46..02052e05db8 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioMapper.java
@@ -24,13 +24,12 @@ import java.util.List;
import java.util.Set;
import javax.annotation.CheckForNull;
import org.apache.ibatis.annotations.Param;
-import org.sonar.db.project.ProjectDto;
public interface PortfolioMapper {
@CheckForNull
PortfolioDto selectByKey(String key);
- List<PortfolioDto> selectByKeys(@Param("keys")List<String> keys);
+ List<PortfolioDto> selectByKeys(@Param("keys") List<String> keys);
@CheckForNull
PortfolioDto selectByUuid(String uuid);
@@ -47,7 +46,7 @@ public interface PortfolioMapper {
void insertReference(PortfolioReferenceDto portfolioReference);
- void insertProject(PortfolioProjectDto portfolioProject);
+ void insertProject(@Param("uuid") String uuid, @Param("portfolioUuid") String portfolioUuid, @Param("projectUuid") String projectUuid, @Param("createdAt") long createdAt);
List<PortfolioDto> selectTree(String portfolioUuid);
@@ -55,7 +54,9 @@ public interface PortfolioMapper {
List<PortfolioDto> selectReferencers(String referenceUuid);
- List<ProjectDto> selectProjects(String portfolioUuid);
+ List<PortfolioProjectDto> selectPortfolioProjects(String portfolioUuid);
+
+ PortfolioProjectDto selectPortfolioProject(@Param("portfolioUuid") String portfolioUuid, @Param("projectUuid") String projectUuid);
List<ReferenceDto> selectAllReferencesToPortfolios();
@@ -93,5 +94,12 @@ public interface PortfolioMapper {
List<ReferenceDto> selectAllReferencesInHierarchy(String rootUuid);
+ void deleteBranch(@Param("portfolioProjectUuid") String portfolioProjectUuid, @Param("branchKey") String branchKey);
+
+ void deleteBranch(@Param("portfolioUuid") String portfolioUuid, @Param("projectUuid") String projectUuid, @Param("branchKey") String branchKey);
+
+ void insertBranch(@Param("uuid") String uuid, @Param("portfolioProjectUuid") String portfolioProjectUuid, @Param("branchKey") String branchKey,
+ @Param("createdAt") long createdAt);
+ Set<String> selectBranches(String portfolioProjectUuid);
}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioProjectDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioProjectDto.java
index ccdf338235b..e78de8efbe6 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioProjectDto.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/portfolio/PortfolioProjectDto.java
@@ -19,10 +19,15 @@
*/
package org.sonar.db.portfolio;
+import java.util.Set;
+
public class PortfolioProjectDto {
private String uuid;
private String portfolioUuid;
+ private String portfolioKey;
private String projectUuid;
+ private String projectKey;
+ private Set<String> branchKeys;
private long createdAt;
public String getUuid() {
@@ -60,4 +65,30 @@ public class PortfolioProjectDto {
this.createdAt = createdAt;
return this;
}
+
+ public String getPortfolioKey() {
+ return portfolioKey;
+ }
+
+ public PortfolioProjectDto setPortfolioKey(String portfolioKey) {
+ this.portfolioKey = portfolioKey;
+ return this;
+ }
+
+ public String getProjectKey() {
+ return projectKey;
+ }
+
+ public PortfolioProjectDto setProjectKey(String projectKey) {
+ this.projectKey = projectKey;
+ return this;
+ }
+
+ public Set<String> getBranchKeys() {
+ return branchKeys;
+ }
+
+ public void setBranchKeys(Set<String> branchKeys) {
+ this.branchKeys = branchKeys;
+ }
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml
index e39f210d60f..519d19ea785 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/portfolio/PortfolioMapper.xml
@@ -2,19 +2,20 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "mybatis-3-mapper.dtd">
<mapper namespace="org.sonar.db.portfolio.PortfolioMapper">
- <sql id="portfolioColumns">
- p.uuid as uuid,
- p.kee as kee,
- p.name as name,
- p.description as description,
- p.private as isPrivate,
- p.root_uuid as rootUuid,
- p.parent_uuid as parentUuid,
- p.selection_mode as selectionMode,
- p.selection_expression as selectionExpression,
- p.created_at as createdAt,
- p.updated_at as updatedAt
- </sql>
+ <sql id="portfolioColumns">
+ p.uuid as uuid,
+ p.kee as kee,
+ p.name as name,
+ p.description as description,
+ p.private as isPrivate,
+ p.branch_name as branchName,
+ p.root_uuid as rootUuid,
+ p.parent_uuid as parentUuid,
+ p.selection_mode as selectionMode,
+ p.selection_expression as selectionExpression,
+ p.created_at as createdAt,
+ p.updated_at as updatedAt
+ </sql>
<sql id="projectColumns">
p.uuid as uuid,
@@ -28,6 +29,24 @@
p.updated_at as updatedAt
</sql>
+ <sql id="portfolioProjectColumns">
+ pp.uuid as portfolioProject_uuid,
+ pp.project_uuid as projectUuid,
+ pp.portfolio_uuid as portfolioUuid,
+ pf.kee as portfolioKey,
+ pp.project_uuid as projectUuid,
+ p.kee as projectKey,
+ pp.created_at as createdAt,
+ ppb.branch_key as branchKey
+ </sql>
+
+ <resultMap id="portfolioProjectResult" type="PortfolioProject" autoMapping="true">
+ <id property="uuid" column="portfolioProject_uuid" />
+ <collection property="branchKeys" ofType="string">
+ <result column="branchKey" />
+ </collection>
+ </resultMap>
+
<select id="selectByUuid" parameterType="String" resultType="Portfolio">
SELECT
<include refid="portfolioColumns"/>
@@ -80,38 +99,54 @@
p.parent_uuid is null
</select>
- <select id="selectProjects" resultType="Project">
+ <select id="selectPortfolioProjectBranches" resultType="string">
+ SELECT ppb.branch_key
+ FROM portfolio_proj_branches ppb
+ WHERE ppb.portfolio_project_uuid = #{id}
+ </select>
+
+ <select id="selectPortfolioProjects" resultMap="portfolioProjectResult">
SELECT
- <include refid="projectColumns"/>
+ <include refid="portfolioProjectColumns"/>
FROM portfolio_projects pp
INNER JOIN projects p on p.uuid = pp.project_uuid
+ INNER JOIN portfolios pf on pf.uuid = pp.portfolio_uuid
+ LEFT OUTER JOIN portfolio_proj_branches ppb on pp.uuid = ppb.portfolio_project_uuid
WHERE
pp.portfolio_uuid=#{portfolioUuid,jdbcType=VARCHAR}
</select>
- <select id="selectAllPortfolioProjects" resultType="org.sonar.db.portfolio.PortfolioProjectDto">
+ <select id="selectPortfolioProject" resultMap="portfolioProjectResult">
+ SELECT
+ <include refid="portfolioProjectColumns"/>
+ FROM portfolio_projects pp
+ INNER JOIN projects p on p.uuid = pp.project_uuid
+ INNER JOIN portfolios pf on pf.uuid = pp.portfolio_uuid
+ LEFT OUTER JOIN portfolio_proj_branches ppb on pp.uuid = ppb.portfolio_project_uuid
+ WHERE
+ pp.portfolio_uuid=#{portfolioUuid,jdbcType=VARCHAR}
+ and pp.project_uuid=#{projectUuid,jdbcType=VARCHAR}
+
+ </select>
+
+ <select id="selectAllPortfolioProjects" resultMap="portfolioProjectResult">
SELECT
- pp.uuid,
- pp.project_uuid as projectUuid,
- pp.portfolio_uuid as portfolioUuid,
- pp.project_uuid as projectUuid,
- pp.created_at as createdAt
+ <include refid="portfolioProjectColumns"/>
FROM portfolio_projects pp
INNER JOIN projects p on p.uuid = pp.project_uuid
+ INNER JOIN portfolios pf on pf.uuid = pp.portfolio_uuid
+ LEFT OUTER JOIN portfolio_proj_branches ppb on pp.uuid = ppb.portfolio_project_uuid
</select>
- <select id="selectAllProjectsInHierarchy" resultType="org.sonar.db.portfolio.PortfolioProjectDto">
+ <select id="selectAllProjectsInHierarchy" resultMap="portfolioProjectResult">
SELECT
- pp.uuid,
- pp.project_uuid as projectUuid,
- pp.portfolio_uuid as portfolioUuid,
- pp.project_uuid as projectUuid,
- pp.created_at as createdAt
+ <include refid="portfolioProjectColumns"/>
FROM portfolio_projects pp
- INNER JOIN portfolios p
- ON pp.portfolio_uuid = p.uuid
+ INNER JOIN projects p on p.uuid = pp.project_uuid
+ INNER JOIN portfolios pf on pp.portfolio_uuid = pf.uuid
+ LEFT OUTER JOIN portfolio_proj_branches ppb on pp.uuid = ppb.portfolio_project_uuid
where
- p.root_uuid = #{rootUuid,jdbcType=VARCHAR}
+ pf.root_uuid = #{rootUuid,jdbcType=VARCHAR}
</select>
<select id="selectReferenceUuids" resultType="String">
@@ -192,6 +227,7 @@
private,
root_uuid,
parent_uuid,
+ branch_name,
selection_mode,
selection_expression,
created_at,
@@ -205,6 +241,7 @@
#{isPrivate,jdbcType=BOOLEAN},
#{rootUuid,jdbcType=VARCHAR},
#{parentUuid,jdbcType=VARCHAR},
+ #{branchName,jdbcType=VARCHAR},
#{selectionMode,jdbcType=VARCHAR},
#{selectionExpression,jdbcType=VARCHAR},
#{createdAt,jdbcType=BIGINT},
@@ -276,6 +313,12 @@
</delete>
<delete id="deleteProjectsByPortfolioUuids" parameterType="String">
+ delete from portfolio_proj_branches
+ where portfolio_project_uuid in
+ (select uuid from portfolio_projects
+ where portfolio_uuid in
+ <foreach collection="uuids" open="(" close=")" item="uuid" separator=",">#{uuid,jdbcType=VARCHAR}</foreach>);
+
DELETE FROM portfolio_projects WHERE portfolio_uuid in
<foreach collection="uuids" open="(" close=")" item="uuid" separator=",">#{uuid,jdbcType=VARCHAR}</foreach>
</delete>
@@ -289,7 +332,8 @@
</delete>
<delete id="deleteAllProjects" parameterType="String">
- DELETE FROM portfolio_projects
+ DELETE FROM portfolio_projects;
+ DELETE FROM portfolio_proj_branches
</delete>
<insert id="insertReference" parameterType="PortfolioReference">
@@ -321,18 +365,28 @@
</delete>
<delete id="deleteProjects" parameterType="String">
+ delete from portfolio_proj_branches
+ where portfolio_project_uuid =
+ (select uuid from portfolio_projects
+ where portfolio_uuid = #{portfolioUuid,jdbcType=VARCHAR});
+
delete from portfolio_projects
where portfolio_uuid = #{portfolioUuid,jdbcType=VARCHAR}
</delete>
- <delete id="deleteProject" parameterType="map">
+ <delete id="deleteProject" parameterType="map">
+ delete from portfolio_proj_branches
+ where portfolio_project_uuid =
+ (select uuid from portfolio_projects
+ where portfolio_uuid = #{portfolioUuid,jdbcType=VARCHAR}
+ and project_uuid = #{projectUuid,jdbcType=VARCHAR});
+
delete from portfolio_projects
where portfolio_uuid = #{portfolioUuid,jdbcType=VARCHAR}
- and
- project_uuid = #{projectUuid,jdbcType=VARCHAR}
+ and project_uuid = #{projectUuid,jdbcType=VARCHAR}
</delete>
- <insert id="insertProject" parameterType="PortfolioProject">
+ <insert id="insertProject" parameterType="map">
INSERT INTO portfolio_projects (
uuid,
portfolio_uuid,
@@ -347,6 +401,30 @@
)
</insert>
+ <insert id="insertBranch" parameterType="map">
+ INSERT INTO portfolio_proj_branches (
+ uuid,
+ portfolio_project_uuid,
+ branch_key,
+ created_at
+ )
+ VALUES (
+ #{uuid,jdbcType=VARCHAR},
+ #{portfolioProjectUuid,jdbcType=VARCHAR},
+ #{branchKey,jdbcType=VARCHAR},
+ #{createdAt,jdbcType=BIGINT}
+ )
+ </insert>
+
+ <delete id="deleteBranch" parameterType="map">
+ delete from portfolio_proj_branches
+ where portfolio_project_uuid =
+ (select uuid from portfolio_projects
+ where portfolio_uuid = #{portfolioUuid,jdbcType=VARCHAR}
+ and project_uuid = #{projectUuid,jdbcType=VARCHAR})
+ and branch_key = #{branchKey,jdbcType=VARCHAR}
+ </delete>
+
<update id="update" parameterType="Portfolio">
update portfolios set
name = #{name,jdbcType=VARCHAR},
@@ -354,6 +432,7 @@
selection_mode = #{selectionMode,jdbcType=VARCHAR},
selection_expression = #{selectionExpression,jdbcType=VARCHAR},
parent_uuid = #{parentUuid,jdbcType=VARCHAR},
+ branch_name = #{branchName,jdbcType=VARCHAR},
root_uuid = #{rootUuid,jdbcType=VARCHAR},
updated_at = #{updatedAt,jdbcType=BIGINT}
where
diff --git a/server/sonar-db-dao/src/schema/schema-sq.ddl b/server/sonar-db-dao/src/schema/schema-sq.ddl
index 7a9d8390bba..8591380930a 100644
--- a/server/sonar-db-dao/src/schema/schema-sq.ddl
+++ b/server/sonar-db-dao/src/schema/schema-sq.ddl
@@ -564,6 +564,14 @@ CREATE TABLE "PLUGINS"(
ALTER TABLE "PLUGINS" ADD CONSTRAINT "PK_PLUGINS" PRIMARY KEY("UUID");
CREATE UNIQUE INDEX "PLUGINS_KEY" ON "PLUGINS"("KEE");
+CREATE TABLE "PORTFOLIO_PROJ_BRANCHES"(
+ "UUID" VARCHAR(40) NOT NULL,
+ "PORTFOLIO_PROJECT_UUID" VARCHAR(40) NOT NULL,
+ "BRANCH_KEY" VARCHAR(255) NOT NULL,
+ "CREATED_AT" BIGINT NOT NULL
+);
+ALTER TABLE "PORTFOLIO_PROJ_BRANCHES" ADD CONSTRAINT "PK_PORTFOLIO_PROJ_BRANCHES" PRIMARY KEY("UUID");
+
CREATE TABLE "PORTFOLIO_PROJECTS"(
"UUID" VARCHAR(40) NOT NULL,
"PORTFOLIO_UUID" VARCHAR(40) NOT NULL,
@@ -593,7 +601,8 @@ CREATE TABLE "PORTFOLIOS"(
"SELECTION_MODE" VARCHAR(50) NOT NULL,
"SELECTION_EXPRESSION" VARCHAR(4000),
"CREATED_AT" BIGINT NOT NULL,
- "UPDATED_AT" BIGINT NOT NULL
+ "UPDATED_AT" BIGINT NOT NULL,
+ "BRANCH_NAME" VARCHAR(255)
);
ALTER TABLE "PORTFOLIOS" ADD CONSTRAINT "PK_PORTFOLIOS" PRIMARY KEY("UUID");
CREATE UNIQUE INDEX "UNIQ_PORTFOLIOS_KEE" ON "PORTFOLIOS"("KEE");
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java
index 593f311cad3..83a30202e65 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/portfolio/PortfolioDaoTest.java
@@ -31,8 +31,8 @@ import org.sonar.db.audit.AuditPersister;
import org.sonar.db.project.ProjectDto;
import static java.util.Collections.emptySet;
-import static java.util.Map.entry;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.ArgumentMatchers.any;
@@ -153,13 +153,18 @@ public class PortfolioDaoTest {
@Test
public void delete() {
+ ProjectDto proj1 = db.components().insertPrivateProjectDto("proj1");
+ ProjectDto app1 = db.components().insertPrivateApplicationDto();
+
PortfolioDto p1 = db.components().insertPrivatePortfolioDto("p1");
PortfolioDto p2 = db.components().insertPrivatePortfolioDto("p2");
PortfolioDto p3 = db.components().insertPrivatePortfolioDto("p3");
PortfolioDto p4 = db.components().insertPrivatePortfolioDto("p4");
- portfolioDao.addProject(session, "p1", "proj1");
- portfolioDao.addProject(session, "p2", "proj1");
+ db.components().addPortfolioProject(p1, proj1);
+ db.components().addPortfolioProject(p2, proj1);
+ db.components().addPortfolioProjectBranch(p1, proj1, "branch1");
+ db.components().addPortfolioProjectBranch(p2, proj1, "branch2");
portfolioDao.addReference(session, "p1", "app1");
portfolioDao.addReference(session, "p2", "app1");
@@ -168,6 +173,8 @@ public class PortfolioDaoTest {
portfolioDao.delete(session, p1);
portfolioDao.delete(session, p3);
+ assertThat(db.select(session, "select branch_key from portfolio_proj_branches")).extracting(m -> m.values().iterator().next())
+ .containsOnly("branch2");
assertThat(db.select(session, "select uuid from portfolios")).extracting(m -> m.values().iterator().next())
.containsOnly("p2", "p4");
assertThat(db.select(session, "select portfolio_uuid from portfolio_references")).extracting(m -> m.values().iterator().next())
@@ -207,16 +214,6 @@ public class PortfolioDaoTest {
.extracting("name", "key", "uuid", "description", "private", "rootUuid", "parentUuid", "selectionMode", "selectionExpression")
.containsExactly("newName", "KEY_name", "name", "newDesc", true, "root", "parent", "newMode", "newExp");
verify(audit).updateComponent(any(), any());
-
- }
-
- @Test
- public void selectKeysByUuids() {
- PortfolioDto root = db.components().insertPrivatePortfolioDto();
- PortfolioDto child1 = addPortfolio(root);
-
- assertThat(portfolioDao.selectKeysByUuids(session, Set.of(root.getUuid(), child1.getUuid())))
- .containsOnly(entry(root.getUuid(), root.getKey()), entry(child1.getUuid(), child1.getKey()));
}
@Test
@@ -253,7 +250,7 @@ public class PortfolioDaoTest {
@Test
public void add_and_select_references() {
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isEmpty();
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).isEmpty();
portfolioDao.addReference(session, "portfolio1", "app1");
portfolioDao.addReference(session, "portfolio1", "app2");
portfolioDao.addReference(session, "portfolio2", "app3");
@@ -378,17 +375,21 @@ public class PortfolioDaoTest {
@Test
public void insert_and_select_projects() {
- db.components().insertPrivateProject("project1");
- db.components().insertPrivateProject("project2");
+ PortfolioDto portfolio1 = db.components().insertPublicPortfolioDto();
+ PortfolioDto portfolio2 = db.components().insertPublicPortfolioDto();
+ PortfolioDto portfolio3 = db.components().insertPublicPortfolioDto();
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isEmpty();
- portfolioDao.addProject(session, "portfolio1", "project1");
- portfolioDao.addProject(session, "portfolio1", "project2");
- portfolioDao.addProject(session, "portfolio2", "project2");
+ ProjectDto project1 = db.components().insertPrivateProjectDto("project1");
+ ProjectDto project2 = db.components().insertPrivateProjectDto("project2");
+
+ assertThat(portfolioDao.selectPortfolioProjects(session, portfolio1.getUuid())).isEmpty();
+ db.components().addPortfolioProject(portfolio1, project1);
+ db.components().addPortfolioProject(portfolio1, project2);
+ db.components().addPortfolioProject(portfolio2, project2);
db.commit();
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).extracting(ProjectDto::getUuid).containsOnly("project1", "project2");
- assertThat(portfolioDao.selectProjects(session, "portfolio2")).extracting(ProjectDto::getUuid).containsOnly("project2");
- assertThat(portfolioDao.selectProjects(session, "portfolio3")).isEmpty();
+ assertThat(portfolioDao.selectPortfolioProjects(session, portfolio1.getUuid())).extracting(PortfolioProjectDto::getProjectUuid).containsOnly("project1", "project2");
+ assertThat(portfolioDao.selectPortfolioProjects(session, portfolio2.getUuid())).extracting(PortfolioProjectDto::getProjectUuid).containsOnly("project2");
+ assertThat(portfolioDao.selectPortfolioProjects(session, portfolio3.getUuid())).isEmpty();
assertThat(db.countRowsOfTable("portfolio_projects")).isEqualTo(3);
assertThat(db.select(session, "select created_at from portfolio_projects"))
@@ -398,56 +399,91 @@ public class PortfolioDaoTest {
@Test
public void delete_projects() {
- db.components().insertPrivateProject("project1");
- db.components().insertPrivateProject("project2");
+ db.components().insertPrivatePortfolioDto("portfolio1");
+ db.components().insertPrivatePortfolioDto("portfolio2");
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isEmpty();
+ db.components().insertPrivateProjectDto("project1");
+ db.components().insertPrivateProjectDto("project2");
+
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).isEmpty();
portfolioDao.addProject(session, "portfolio1", "project1");
portfolioDao.addProject(session, "portfolio1", "project2");
portfolioDao.addProject(session, "portfolio2", "project2");
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isNotEmpty();
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).isNotEmpty();
portfolioDao.deleteProjects(session, "portfolio1");
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isEmpty();
- assertThat(portfolioDao.selectProjects(session, "portfolio2")).extracting(ProjectDto::getUuid).containsOnly("project2");
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).isEmpty();
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio2")).extracting(PortfolioProjectDto::getProjectUuid).containsOnly("project2");
+ }
+
+ @Test
+ public void add_and_delete_selected_branches() {
+ PortfolioDto portfolio1 = db.components().insertPrivatePortfolioDto("portfolio1");
+ ProjectDto project1 = db.components().insertPrivateProjectDto("project1");
+ db.components().addPortfolioProject(portfolio1, project1);
+
+ assertThat(db.countRowsOfTable(db.getSession(), "portfolio_proj_branches")).isZero();
+ assertThat(portfolioDao.selectPortfolioProjectOrFail(db.getSession(), portfolio1.getUuid(), project1.getUuid()).getBranchKeys()).isEmpty();
+
+ db.components().addPortfolioProjectBranch(portfolio1, project1, "branch1");
+ assertThat(db.countRowsOfTable(db.getSession(), "portfolio_proj_branches")).isOne();
+ PortfolioProjectDto portfolioProject = portfolioDao.selectPortfolioProjectOrFail(db.getSession(), portfolio1.getUuid(), project1.getUuid());
+ assertThat(portfolioProject.getBranchKeys()).containsOnly("branch1");
+
+ portfolioDao.deleteBranch(db.getSession(), portfolio1.getUuid(), project1.getUuid(), "branch1");
+ assertThat(db.countRowsOfTable(db.getSession(), "portfolio_proj_branches")).isZero();
+ assertThat(portfolioDao.selectPortfolioProjectOrFail(db.getSession(), portfolio1.getUuid(), project1.getUuid()).getBranchKeys()).isEmpty();
+ }
+
+ @Test
+ public void delete_nonexisting_branch_doesnt_fail() {
+ DbSession session = db.getSession();
+ assertThatCode(() -> portfolioDao.deleteBranch(session, "nonexisting1", "nonexisting2", "branch1"))
+ .doesNotThrowAnyException();
}
@Test
public void delete_project() {
- db.components().insertPrivateProject("project1");
- db.components().insertPrivateProject("project2");
+ db.components().insertPrivatePortfolioDto("portfolio1");
+ db.components().insertPrivatePortfolioDto("portfolio2");
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isEmpty();
+ db.components().insertPrivateProjectDto("project1");
+ db.components().insertPrivateProjectDto("project2");
+
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).isEmpty();
portfolioDao.addProject(session, "portfolio1", "project1");
portfolioDao.addProject(session, "portfolio1", "project2");
portfolioDao.addProject(session, "portfolio2", "project2");
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).isNotEmpty();
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).isNotEmpty();
portfolioDao.deleteProject(session, "portfolio1", "project2");
- assertThat(portfolioDao.selectProjects(session, "portfolio1")).extracting(ProjectDto::getUuid).containsOnly("project1");
- assertThat(portfolioDao.selectProjects(session, "portfolio2")).extracting(ProjectDto::getUuid).containsOnly("project2");
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio1")).extracting(PortfolioProjectDto::getProjectUuid).containsOnly("project1");
+ assertThat(portfolioDao.selectPortfolioProjects(session, "portfolio2")).extracting(PortfolioProjectDto::getProjectUuid).containsOnly("project2");
}
@Test
public void selectAllProjectsInHierarchy() {
- db.components().insertPrivateProject("p1");
- db.components().insertPrivateProject("p2");
- db.components().insertPrivateProject("p3");
- db.components().insertPrivateProject("p4");
+ ProjectDto p1 = db.components().insertPrivateProjectDto("p1");
+ ProjectDto p2 = db.components().insertPrivateProjectDto("p2");
+ ProjectDto p3 = db.components().insertPrivateProjectDto("p3");
+ ProjectDto p4 = db.components().insertPrivateProjectDto("p4");
PortfolioDto root = db.components().insertPrivatePortfolioDto("root");
PortfolioDto child1 = addPortfolio(root, "child1");
PortfolioDto child11 = addPortfolio(child1, "child11");
PortfolioDto root2 = db.components().insertPrivatePortfolioDto("root2");
- portfolioDao.addProject(session, root.getUuid(), "p1");
- portfolioDao.addProject(session, child1.getUuid(), "p2");
- portfolioDao.addProject(session, child11.getUuid(), "p3");
- portfolioDao.addProject(session, root2.getUuid(), "p4");
+ db.components().addPortfolioProject(root, p1);
+ db.components().addPortfolioProject(child1, p2);
+ db.components().addPortfolioProject(child11, p3);
+ db.components().addPortfolioProject(root2, p4);
+
+ db.components().addPortfolioProjectBranch(root, p1, "branch1");
session.commit();
assertThat(portfolioDao.selectAllProjectsInHierarchy(session, root.getUuid()))
- .extracting(PortfolioProjectDto::getProjectUuid).containsExactly("p1", "p2", "p3");
+ .extracting(PortfolioProjectDto::getProjectUuid, PortfolioProjectDto::getBranchKeys)
+ .containsExactlyInAnyOrder(tuple("p1", Set.of("branch1")), tuple("p2", emptySet()), tuple("p3", emptySet()));
assertThat(portfolioDao.selectAllProjectsInHierarchy(session, "nonexisting")).isEmpty();
}
@@ -463,14 +499,18 @@ public class PortfolioDaoTest {
PortfolioDto child11 = addPortfolio(child1);
PortfolioDto root2 = db.components().insertPrivatePortfolioDto();
- portfolioDao.addProject(session, root.getUuid(), "p1");
+ String portfolioProjectUuid = portfolioDao.addProject(session, root.getUuid(), "p1");
portfolioDao.addProject(session, child1.getUuid(), "p2");
portfolioDao.addProject(session, child11.getUuid(), "p3");
portfolioDao.addProject(session, root2.getUuid(), "p4");
+ portfolioDao.addBranch(session, portfolioProjectUuid, "branch1");
+
assertThat(db.countRowsOfTable(session, "portfolio_projects")).isEqualTo(4);
+ assertThat(db.countRowsOfTable(session, "portfolio_proj_branches")).isOne();
portfolioDao.deleteAllProjects(session);
assertThat(db.countRowsOfTable(session, "portfolio_projects")).isZero();
+ assertThat(db.countRowsOfTable(session, "portfolio_proj_branches")).isZero();
}
private PortfolioDto addPortfolio(PortfolioDto parent) {
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 402b3a5b401..b47fe7a9d99 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
@@ -28,6 +28,7 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.portfolio.PortfolioDto;
+import org.sonar.db.portfolio.PortfolioProjectDto;
import org.sonar.db.project.ProjectDto;
import static com.google.common.base.Preconditions.checkArgument;
@@ -301,6 +302,12 @@ public class ComponentDbTester {
db.commit();
}
+ public void addPortfolioProjectBranch(PortfolioDto portfolio, ProjectDto project, String branchKey) {
+ PortfolioProjectDto portfolioProject = dbClient.portfolioDao().selectPortfolioProjectOrFail(dbSession, portfolio.getUuid(), project.getUuid());
+ dbClient.portfolioDao().addBranch(db.getSession(), portfolioProject.getUuid(), branchKey);
+ db.commit();
+ }
+
public final ComponentDto insertPublicApplication() {
return insertPublicApplication(defaults());
}