@@ -455,7 +455,11 @@ class PurgeCommands { | |||
public void deleteProjectInPortfolios(String rootUuid) { | |||
profiler.start("deleteProjectInPortfolios (portfolio_projects)"); | |||
// delete selected project if it's only selecting a single branch corresponding to rootUuid | |||
purgeMapper.deletePortfolioProjectsByBranchUuid(rootUuid); | |||
// delete selected branches if branch is rootUuid or if it's part of a project that is rootUuid | |||
purgeMapper.deletePortfolioProjectBranchesByBranchUuid(rootUuid); | |||
// delete selected project if project is rootUuid | |||
purgeMapper.deletePortfolioProjectsByProjectUuid(rootUuid); | |||
session.commit(); | |||
profiler.stop(); |
@@ -165,7 +165,7 @@ public class PurgeDao implements Dao { | |||
private static final class NewCodePeriodAnalysisFilter implements Predicate<PurgeableAnalysisDto> { | |||
@Nullable | |||
private String analysisUuid; | |||
private final String analysisUuid; | |||
private NewCodePeriodAnalysisFilter(PurgeMapper mapper, String componentUuid) { | |||
this.analysisUuid = mapper.selectSpecificAnalysisNewCodePeriod(componentUuid); |
@@ -147,6 +147,8 @@ public interface PurgeMapper { | |||
void deleteApplicationBranchProjectBranchesByProjectBranchUuid(@Param("projectBranchUuid") String projectBranchUuid); | |||
void deletePortfolioProjectsByBranchUuid(@Param("branchUuid") String branchUuid); | |||
void deletePortfolioProjectsByProjectUuid(@Param("projectUuid") String projectUuid); | |||
void deletePortfolioProjectBranchesByBranchUuid(@Param("branchUuid") String branchUuid); |
@@ -349,6 +349,19 @@ | |||
WHERE project_branch_uuid=#{projectBranchUuid,jdbcType=VARCHAR} | |||
</delete> | |||
<delete id="deletePortfolioProjectsByBranchUuid" parameterType="map"> | |||
<!-- deletes selected projects that were only selecting the branch being deleted --> | |||
DELETE | |||
FROM portfolio_projects | |||
WHERE uuid in ( | |||
SELECT ppb.portfolio_project_uuid FROM portfolio_proj_branches ppb | |||
<!-- branch was selected --> | |||
WHERE ppb.branch_uuid = #{branchUuid,jdbcType=VARCHAR} | |||
<!-- and was the only one selected in the project --> | |||
AND (SELECT count(*) FROM portfolio_proj_branches ppb2 WHERE ppb2.portfolio_project_uuid = ppb.portfolio_project_uuid) = 1 | |||
) | |||
</delete> | |||
<delete id="deletePortfolioProjectsByProjectUuid" parameterType="map"> | |||
DELETE | |||
FROM portfolio_projects |
@@ -56,7 +56,6 @@ import org.sonar.db.user.UserDto; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
import static java.util.Arrays.asList; | |||
import static java.util.Collections.emptyList; | |||
import static java.util.Collections.singleton; | |||
import static java.util.Collections.singletonList; | |||
import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic; | |||
@@ -654,7 +653,7 @@ public class PurgeCommandsTest { | |||
} | |||
@Test | |||
public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios() { | |||
public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios_if_root_is_branch() { | |||
var portfolio1 = dbTester.components().insertPrivatePortfolioDto(); | |||
var portfolio2 = dbTester.components().insertPrivatePortfolioDto(); | |||
dbTester.components().insertPrivatePortfolio(); | |||
@@ -676,6 +675,24 @@ public class PurgeCommandsTest { | |||
.containsExactlyInAnyOrder(tuple(portfolio1.getUuid(), anotherProject.getUuid(), singleton("anotherProjectBranch"))); | |||
} | |||
@Test | |||
public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios_if_root_is_project_only_selecting_a_single_branch() { | |||
var portfolio1 = dbTester.components().insertPrivatePortfolioDto(); | |||
dbTester.components().insertPrivatePortfolio(); | |||
ProjectDto project = dbTester.components().insertPrivateProjectDto(); | |||
dbTester.components().addPortfolioProject(portfolio1, project); | |||
dbTester.components().addPortfolioProjectBranch(portfolio1, project, "projectBranch"); | |||
PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2); | |||
purgeCommands.deleteProjectInPortfolios(project.getUuid()); | |||
assertThat(dbTester.getDbClient().portfolioDao().selectAllPortfolioProjects(dbTester.getSession())).isEmpty(); | |||
assertThat(dbTester.countRowsOfTable("portfolio_proj_branches")).isZero(); | |||
assertThat(dbTester.countRowsOfTable("portfolio_projects")).isZero(); | |||
} | |||
@Test | |||
public void deleteProjectInPortfolios_deletes_branch_from_portfolios_if_root_is_branch() { | |||
var portfolio1 = dbTester.components().insertPrivatePortfolioDto(); |
@@ -0,0 +1,74 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonarqube.ws.client.views; | |||
import javax.annotation.Generated; | |||
/** | |||
* This is part of the internal API. | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_project_branch">Further information about this action online (including a response example)</a> | |||
* @since 9.2 | |||
*/ | |||
@Generated("sonar-ws-generator") | |||
public class AddProjectBranchRequest { | |||
private String branch; | |||
private String key; | |||
private String project; | |||
/** | |||
* This is a mandatory parameter. | |||
* Example value: "feature/my_branch" | |||
*/ | |||
public AddProjectBranchRequest setBranch(String branch) { | |||
this.branch = branch; | |||
return this; | |||
} | |||
public String getBranch() { | |||
return branch; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
*/ | |||
public AddProjectBranchRequest setKey(String key) { | |||
this.key = key; | |||
return this; | |||
} | |||
public String getKey() { | |||
return key; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
* Example value: "my_project" | |||
*/ | |||
public AddProjectBranchRequest setProject(String project) { | |||
this.project = project; | |||
return this; | |||
} | |||
public String getProject() { | |||
return project; | |||
} | |||
} |
@@ -19,6 +19,7 @@ | |||
*/ | |||
package org.sonarqube.ws.client.views; | |||
import java.util.List; | |||
import javax.annotation.Generated; | |||
/** | |||
@@ -33,6 +34,7 @@ public class CreateRequest { | |||
private String description; | |||
private String key; | |||
private String name; | |||
private String qualifier; | |||
private String visibility; | |||
/** | |||
@@ -69,6 +71,24 @@ public class CreateRequest { | |||
return name; | |||
} | |||
/** | |||
* Possible values: | |||
* <ul> | |||
* <li>"VW"</li> | |||
* <li>"APP"</li> | |||
* </ul> | |||
* @deprecated since 7.3 | |||
*/ | |||
@Deprecated | |||
public CreateRequest setQualifier(String qualifier) { | |||
this.qualifier = qualifier; | |||
return this; | |||
} | |||
public String getQualifier() { | |||
return qualifier; | |||
} | |||
/** | |||
* Possible values: | |||
* <ul> |
@@ -0,0 +1,74 @@ | |||
/* | |||
* SonarQube | |||
* Copyright (C) 2009-2021 SonarSource SA | |||
* mailto:info AT sonarsource DOT com | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 3 of the License, or (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public License | |||
* along with this program; if not, write to the Free Software Foundation, | |||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
*/ | |||
package org.sonarqube.ws.client.views; | |||
import javax.annotation.Generated; | |||
/** | |||
* This is part of the internal API. | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/remove_project_branch">Further information about this action online (including a response example)</a> | |||
* @since 9.2 | |||
*/ | |||
@Generated("sonar-ws-generator") | |||
public class RemoveProjectBranchRequest { | |||
private String branch; | |||
private String key; | |||
private String project; | |||
/** | |||
* This is a mandatory parameter. | |||
* Example value: "feature/my_branch" | |||
*/ | |||
public RemoveProjectBranchRequest setBranch(String branch) { | |||
this.branch = branch; | |||
return this; | |||
} | |||
public String getBranch() { | |||
return branch; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
*/ | |||
public RemoveProjectBranchRequest setKey(String key) { | |||
this.key = key; | |||
return this; | |||
} | |||
public String getKey() { | |||
return key; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
* Example value: "my_project" | |||
*/ | |||
public RemoveProjectBranchRequest setProject(String project) { | |||
this.project = project; | |||
return this; | |||
} | |||
public String getProject() { | |||
return project; | |||
} | |||
} |
@@ -93,7 +93,6 @@ public class SearchRequest { | |||
/** | |||
* Possible values: | |||
* <ul> | |||
* <li>"APP"</li> | |||
* <li>"VW"</li> | |||
* <li>"SVW"</li> | |||
* </ul> |
@@ -30,9 +30,21 @@ import javax.annotation.Generated; | |||
@Generated("sonar-ws-generator") | |||
public class SetRegexpModeRequest { | |||
private String branch; | |||
private String portfolio; | |||
private String regexp; | |||
/** | |||
*/ | |||
public SetRegexpModeRequest setBranch(String branch) { | |||
this.branch = branch; | |||
return this; | |||
} | |||
public String getBranch() { | |||
return branch; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
*/ |
@@ -30,8 +30,20 @@ import javax.annotation.Generated; | |||
@Generated("sonar-ws-generator") | |||
public class SetRemainingProjectsModeRequest { | |||
private String branch; | |||
private String portfolio; | |||
/** | |||
*/ | |||
public SetRemainingProjectsModeRequest setBranch(String branch) { | |||
this.branch = branch; | |||
return this; | |||
} | |||
public String getBranch() { | |||
return branch; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
*/ | |||
@@ -43,5 +55,4 @@ public class SetRemainingProjectsModeRequest { | |||
public String getPortfolio() { | |||
return portfolio; | |||
} | |||
} |
@@ -31,9 +31,21 @@ import javax.annotation.Generated; | |||
@Generated("sonar-ws-generator") | |||
public class SetTagsModeRequest { | |||
private String branch; | |||
private String portfolio; | |||
private List<String> tags; | |||
/** | |||
*/ | |||
public SetTagsModeRequest setBranch(String branch) { | |||
this.branch = branch; | |||
return this; | |||
} | |||
public String getBranch() { | |||
return branch; | |||
} | |||
/** | |||
* This is a mandatory parameter. | |||
*/ |
@@ -73,16 +73,15 @@ public class ViewsService extends BaseService { | |||
* | |||
* This is part of the internal API. | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_sub_view">Further information about this action online (including a response example)</a> | |||
* @since 1.0 | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_project_branch">Further information about this action online (including a response example)</a> | |||
* @since 9.2 | |||
*/ | |||
public void addSubView(AddSubViewRequest request) { | |||
public void addProjectBranch(AddProjectBranchRequest request) { | |||
call( | |||
new PostRequest(path("add_sub_view")) | |||
.setParam("description", request.getDescription()) | |||
new PostRequest(path("add_project_branch")) | |||
.setParam("branch", request.getBranch()) | |||
.setParam("key", request.getKey()) | |||
.setParam("name", request.getName()) | |||
.setParam("subKey", request.getSubKey()) | |||
.setParam("project", request.getProject()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
} | |||
@@ -90,13 +89,17 @@ public class ViewsService extends BaseService { | |||
/** | |||
* | |||
* This is part of the internal API. | |||
* This is a GET request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/app">Further information about this action online (including a response example)</a> | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_sub_view">Further information about this action online (including a response example)</a> | |||
* @since 1.0 | |||
*/ | |||
public String app() { | |||
return call( | |||
new GetRequest(path("app")) | |||
public void addSubView(AddSubViewRequest request) { | |||
call( | |||
new PostRequest(path("add_sub_view")) | |||
.setParam("description", request.getDescription()) | |||
.setParam("key", request.getKey()) | |||
.setParam("name", request.getName()) | |||
.setParam("subKey", request.getSubKey()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
} | |||
@@ -114,6 +117,7 @@ public class ViewsService extends BaseService { | |||
.setParam("description", request.getDescription()) | |||
.setParam("key", request.getKey()) | |||
.setParam("name", request.getName()) | |||
.setParam("qualifier", request.getQualifier()) | |||
.setParam("visibility", request.getVisibility()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
@@ -125,7 +129,9 @@ public class ViewsService extends BaseService { | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/define">Further information about this action online (including a response example)</a> | |||
* @since 1.0 | |||
* @deprecated since 9.2 | |||
*/ | |||
@Deprecated | |||
public void define(DefineRequest request) { | |||
call( | |||
new PostRequest(path("define")) | |||
@@ -140,7 +146,9 @@ public class ViewsService extends BaseService { | |||
* This is a GET request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/definition">Further information about this action online (including a response example)</a> | |||
* @since 2.0 | |||
* @deprecated since 9.2 | |||
*/ | |||
@Deprecated | |||
public String definition() { | |||
return call( | |||
new GetRequest(path("definition")) | |||
@@ -277,14 +285,15 @@ public class ViewsService extends BaseService { | |||
* | |||
* This is part of the internal API. | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/run">Further information about this action online (including a response example)</a> | |||
* @since 1.0 | |||
* @deprecated since 7.1 | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/remove_project_branch">Further information about this action online (including a response example)</a> | |||
* @since 9.2 | |||
*/ | |||
@Deprecated | |||
public String run() { | |||
return call( | |||
new PostRequest(path("run")) | |||
public void removeProjectBranch(RemoveProjectBranchRequest request) { | |||
call( | |||
new PostRequest(path("remove_project_branch")) | |||
.setParam("branch", request.getBranch()) | |||
.setParam("key", request.getKey()) | |||
.setParam("project", request.getProject()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
} | |||
@@ -320,7 +329,7 @@ public class ViewsService extends BaseService { | |||
new PostRequest(path("set_manual_mode")) | |||
.setParam("portfolio", request.getPortfolio()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
).content(); | |||
} | |||
/** | |||
@@ -335,23 +344,24 @@ public class ViewsService extends BaseService { | |||
new PostRequest(path("set_none_mode")) | |||
.setParam("portfolio", request.getPortfolio()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
).content(); | |||
} | |||
/** | |||
* | |||
* This is part of the internal API. | |||
* This is a POST request. | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/set_remaining_projects_mode">Further information about this action online (including a response example)</a> | |||
* @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/set_regexp_mode">Further information about this action online (including a response example)</a> | |||
* @since 7.4 | |||
*/ | |||
public void setRegexpMode(SetRegexpModeRequest request) { | |||
call( | |||
new PostRequest(path("set_regexp_mode")) | |||
.setParam("branch", request.getBranch()) | |||
.setParam("portfolio", request.getPortfolio()) | |||
.setParam("regexp", request.getRegexp()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
).content(); | |||
} | |||
/** | |||
@@ -364,9 +374,10 @@ public class ViewsService extends BaseService { | |||
public void setRemainingProjectsMode(SetRemainingProjectsModeRequest request) { | |||
call( | |||
new PostRequest(path("set_remaining_projects_mode")) | |||
.setParam("branch", request.getBranch()) | |||
.setParam("portfolio", request.getPortfolio()) | |||
.setMediaType(MediaTypes.JSON) | |||
).content(); | |||
).content(); | |||
} | |||
/** | |||
@@ -379,6 +390,7 @@ public class ViewsService extends BaseService { | |||
public void setTagsMode(SetTagsModeRequest request) { | |||
call( | |||
new PostRequest(path("set_tags_mode")) | |||
.setParam("branch", request.getBranch()) | |||
.setParam("portfolio", request.getPortfolio()) | |||
.setParam("tags", request.getTags() == null ? null : request.getTags().stream().collect(Collectors.joining(","))) | |||
.setMediaType(MediaTypes.JSON) |