aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2017-06-29 10:42:55 +0200
committerJulien Lancelot <julien.lancelot@sonarsource.com>2017-07-04 16:29:36 +0200
commit744a413b6c0f540117da5cc0ace02c72e81926f3 (patch)
tree13fc9d991c080e119ad4f2e30896eff6e5b6c252
parent119b1079c42cb176d22773e0e029023152a79c4b (diff)
downloadsonarqube-744a413b6c0f540117da5cc0ace02c72e81926f3.tar.gz
sonarqube-744a413b6c0f540117da5cc0ace02c72e81926f3.zip
SONAR-9482 Use query object to count active rules in db
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java104
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java25
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java7
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml43
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java127
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java20
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java10
7 files changed, 195 insertions, 141 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java
new file mode 100644
index 00000000000..02303b9b8be
--- /dev/null
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java
@@ -0,0 +1,104 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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.sonar.db.qualityprofile;
+
+import java.util.List;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+import org.sonar.api.rule.RuleStatus;
+import org.sonar.core.util.stream.MoreCollectors;
+import org.sonar.db.organization.OrganizationDto;
+
+import static com.google.common.base.Preconditions.checkState;
+
+public class ActiveRuleCountQuery {
+
+ private final OrganizationDto organization;
+ private final List<String> profileUuids;
+ private final RuleStatus ruleStatus;
+ private final String inheritance;
+
+ public ActiveRuleCountQuery(Builder builder) {
+ this.profileUuids = builder.profiles.stream().map(QProfileDto::getKee).collect(MoreCollectors.toList());
+ this.ruleStatus = builder.ruleStatus;
+ this.inheritance = builder.inheritance;
+ this.organization = builder.organization;
+ }
+
+ public OrganizationDto getOrganization() {
+ return organization;
+ }
+
+ public List<String> getProfileUuids() {
+ return profileUuids;
+ }
+
+ /**
+ * When no rule status is set, removed rules are not returned
+ */
+ @CheckForNull
+ public RuleStatus getRuleStatus() {
+ return ruleStatus;
+ }
+
+ @CheckForNull
+ public String getInheritance() {
+ return inheritance;
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private OrganizationDto organization;
+ private List<QProfileDto> profiles;
+ private RuleStatus ruleStatus;
+ private String inheritance;
+
+ public Builder setOrganization(OrganizationDto organization) {
+ this.organization = organization;
+ return this;
+ }
+
+ public Builder setProfiles(List<QProfileDto> profiles) {
+ this.profiles = profiles;
+ return this;
+ }
+
+ public Builder setRuleStatus(@Nullable RuleStatus ruleStatus) {
+ this.ruleStatus = ruleStatus;
+ return this;
+ }
+
+ public Builder setInheritance(@Nullable String inheritance) {
+ this.inheritance = inheritance;
+ return this;
+ }
+
+ public ActiveRuleCountQuery build() {
+ checkState(organization != null, "Organization cannot be null");
+ checkState(profiles != null, "Profiles cannot be null");
+ return new ActiveRuleCountQuery(this);
+ }
+ }
+
+}
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java
index e62d881de6d..a699eab7870 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java
@@ -24,15 +24,14 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
-import org.sonar.api.rule.RuleStatus;
import org.sonar.db.Dao;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbSession;
-import org.sonar.db.KeyLongValue;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.rule.RuleParamDto;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
+import static org.sonar.db.KeyLongValue.toMap;
public class ActiveRuleDao implements Dao {
@@ -166,25 +165,9 @@ public class ActiveRuleDao implements Dao {
DatabaseUtils.executeLargeUpdates(activeRuleIds, mapper::deleteParamsByActiveRuleIds);
}
- /**
- * Active rule on removed rule are NOT taken into account
- */
- public Map<String, Long> countActiveRulesByProfileUuid(DbSession dbSession, OrganizationDto organization) {
- return KeyLongValue.toMap(
- mapper(dbSession).countActiveRulesByProfileUuid(organization.getUuid()));
- }
-
- public Map<String, Long> countActiveRulesForRuleStatusByProfileUuid(DbSession dbSession, OrganizationDto organization, RuleStatus ruleStatus) {
- return KeyLongValue.toMap(
- mapper(dbSession).countActiveRulesForRuleStatusByProfileUuid(organization.getUuid(), ruleStatus));
- }
-
- /**
- * Active rule on removed rule are NOT taken into account
- */
- public Map<String, Long> countActiveRulesForInheritanceByProfileUuid(DbSession dbSession, OrganizationDto organization, String inheritance) {
- return KeyLongValue.toMap(
- mapper(dbSession).countActiveRulesForInheritanceByProfileUuid(organization.getUuid(), inheritance));
+ public Map<String, Long> countActiveRulesByQuery(DbSession dbSession, ActiveRuleCountQuery query) {
+ return toMap(executeLargeInputs(query.getProfileUuids(),
+ partition -> mapper(dbSession).countActiveRulesByQuery(query.getOrganization().getUuid(), partition, query.getRuleStatus(), query.getInheritance())));
}
private static ActiveRuleMapper mapper(DbSession dbSession) {
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java
index 5c384a20ccd..6a64c21ee4e 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java
@@ -22,6 +22,7 @@ package org.sonar.db.qualityprofile;
import java.util.Collection;
import java.util.List;
import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.apache.ibatis.annotations.Param;
import org.sonar.api.rule.RuleStatus;
import org.sonar.db.KeyLongValue;
@@ -69,9 +70,7 @@ public interface ActiveRuleMapper {
List<ActiveRuleParamDto> selectParamsByActiveRuleIds(@Param("ids") List<Integer> ids);
- List<KeyLongValue> countActiveRulesByProfileUuid(@Param("organizationUuid") String organizationUuid);
+ List<KeyLongValue> countActiveRulesByQuery(@Param("organizationUuid") String organizationUuid, @Param("profileUuids") List<String> profileUuids,
+ @Nullable @Param("ruleStatus") RuleStatus ruleStatus, @Param("inheritance") String inheritance);
- List<KeyLongValue> countActiveRulesForRuleStatusByProfileUuid(@Param("organizationUuid") String organizationUuid, @Param("ruleStatus") RuleStatus ruleStatus);
-
- List<KeyLongValue> countActiveRulesForInheritanceByProfileUuid(@Param("organizationUuid") String organizationUuid, @Param("inheritance") String inheritance);
}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
index 840467e7e8b..29ac1dc7481 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
@@ -246,38 +246,31 @@
</where>
</select>
- <select id="countActiveRulesByProfileUuid" resultType="KeyLongValue" parameterType="map">
+ <select id="countActiveRulesByQuery" resultType="KeyLongValue" parameterType="map">
select oqp.uuid as "key", count(ar.id) as "value"
from active_rules ar
inner join rules_profiles rp on rp.id = ar.profile_id
inner join org_qprofiles oqp on oqp.rules_profile_uuid = rp.kee
inner join rules r on r.id = ar.rule_id
- where oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
- and r.status != 'REMOVED'
- group by oqp.uuid
- </select>
-
- <select id="countActiveRulesForRuleStatusByProfileUuid" resultType="KeyLongValue" parameterType="map">
- select oqp.uuid as "key", count(ar.id) as "value"
- from active_rules ar
- inner join rules_profiles rp on rp.id = ar.profile_id
- inner join org_qprofiles oqp on oqp.rules_profile_uuid = rp.kee
- inner join rules r on r.id = ar.rule_id
- where oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
- and r.status = #{ruleStatus, jdbcType=VARCHAR}
+ <where>
+ oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
+ and <foreach collection="profileUuids" item="profileUuid" open="(" separator=" or " close=")">
+ oqp.uuid = #{profileUuid, jdbcType=VARCHAR}
+ </foreach>
+ <choose>
+ <when test="ruleStatus == null">
+ and r.status != 'REMOVED'
+ </when>
+ <otherwise>
+ and r.status = #{ruleStatus, jdbcType=VARCHAR}
+ </otherwise>
+ </choose>
+ <if test="inheritance != null">
+ and ar.inheritance = #{inheritance, jdbcType=VARCHAR}
+ </if>
+ </where>
group by oqp.uuid
</select>
- <select id="countActiveRulesForInheritanceByProfileUuid" resultType="KeyLongValue" parameterType="map">
- select oqp.uuid as "key", count(ar.id) as "value"
- from active_rules ar
- inner join rules_profiles rp on rp.id = ar.profile_id
- inner join org_qprofiles oqp on oqp.rules_profile_uuid = rp.kee
- inner join rules r on r.id = ar.rule_id
- where oqp.organization_uuid = #{organizationUuid, jdbcType=VARCHAR}
- and ar.inheritance = #{inheritance, jdbcType=VARCHAR}
- and r.status != 'REMOVED'
- group by oqp.uuid
- </select>
</mapper>
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java
index 62c4c989d77..8eb040b9d0b 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java
@@ -19,15 +19,12 @@
*/
package org.sonar.db.qualityprofile;
-import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
-import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.utils.System2;
@@ -35,17 +32,19 @@ import org.sonar.api.utils.internal.TestSystem2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.rule.RuleDefinitionDto;
import org.sonar.db.rule.RuleParamDto;
-import org.sonar.db.rule.RuleTesting;
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.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.entry;
import static org.assertj.core.api.Assertions.tuple;
-import static org.assertj.core.data.MapEntry.entry;
+import static org.sonar.api.rule.RuleStatus.BETA;
+import static org.sonar.api.rule.RuleStatus.READY;
+import static org.sonar.api.rule.RuleStatus.REMOVED;
import static org.sonar.api.rule.Severity.BLOCKER;
import static org.sonar.api.rule.Severity.MAJOR;
import static org.sonar.db.qualityprofile.ActiveRuleDto.INHERITED;
@@ -86,7 +85,7 @@ public class ActiveRuleDaoTest {
rule1 = db.rules().insert();
rule2 = db.rules().insert();
rule3 = db.rules().insert();
- removedRule = db.rules().insert(r -> r.setStatus(RuleStatus.REMOVED));
+ removedRule = db.rules().insert(r -> r.setStatus(REMOVED));
rule1Param1 = new RuleParamDto()
.setName("param1")
@@ -128,7 +127,7 @@ public class ActiveRuleDaoTest {
underTest.insert(dbSession, activeRule3);
dbSession.commit();
- assertThat(underTest.selectByRuleIds(dbSession, organization, Collections.singletonList(rule1.getId())))
+ assertThat(underTest.selectByRuleIds(dbSession, organization, singletonList(rule1.getId())))
.extracting("key").containsOnly(activeRule1.getKey(), activeRule3.getKey());
assertThat(underTest.selectByRuleIds(dbSession, organization, newArrayList(rule1.getId(), rule2.getId())))
.extracting("key").containsOnly(activeRule1.getKey(), activeRule2.getKey(), activeRule3.getKey());
@@ -516,101 +515,67 @@ public class ActiveRuleDaoTest {
}
@Test
- public void test_countActiveRulesByProfileKey_for_a_specified_organization() {
+ public void countActiveRulesByQuery_filter_by_profiles() {
db.qualityProfiles().activateRule(profile1, rule1);
db.qualityProfiles().activateRule(profile1, rule2);
+ db.qualityProfiles().activateRule(profile1, removedRule);
db.qualityProfiles().activateRule(profile2, rule1);
+ QProfileDto profileWithoutActiveRule = db.qualityProfiles().insert(organization);
- Map<String, Long> counts = underTest.countActiveRulesByProfileUuid(dbSession, organization);
-
- assertThat(counts).containsOnly(
+ ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).build()))
+ .containsOnly(entry(profile1.getKee(), 2L), entry(profile2.getKee(), 1L));
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(singletonList(profileWithoutActiveRule)).build())).isEmpty();
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2, profileWithoutActiveRule)).build())).containsOnly(
entry(profile1.getKee(), 2L),
entry(profile2.getKee(), 1L));
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(emptyList()).build())).isEmpty();
}
@Test
- public void countActiveRulesByProfileKey_returns_empty_map_if_organization_does_not_exist() {
- Map<String, Long> counts = underTest.countActiveRulesByProfileUuid(dbSession, OrganizationTesting.newOrganizationDto());
-
- assertThat(counts).isEmpty();
- }
-
- @Test
- public void countActiveRulesByProfileKey_returns_empty_map_if_profile_does_not_have_active_rules() {
- Map<String, Long> counts = underTest.countActiveRulesByProfileUuid(dbSession, organization);
-
- assertThat(counts).isEmpty();
- }
-
- @Test
- public void countActiveRulesByProfileKey_ignores_removed_rules() {
+ public void countActiveRulesByQuery_filter_by_rule_status() {
+ RuleDefinitionDto betaRule = db.rules().insert(r -> r.setStatus(BETA));
db.qualityProfiles().activateRule(profile1, rule1);
+ db.qualityProfiles().activateRule(profile1, rule2);
+ db.qualityProfiles().activateRule(profile1, betaRule);
db.qualityProfiles().activateRule(profile1, removedRule);
+ db.qualityProfiles().activateRule(profile2, rule1);
+ db.qualityProfiles().activateRule(profile2, betaRule);
- Map<String, Long> counts = underTest.countActiveRulesByProfileUuid(dbSession, organization);
-
- assertThat(counts).containsExactly(entry(profile1.getKee(), 1L));
+ ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).setRuleStatus(BETA).build()))
+ .containsOnly(entry(profile1.getKee(), 1L), entry(profile2.getKee(), 1L));
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(singletonList(profile1)).setRuleStatus(READY).build()))
+ .containsOnly(entry(profile1.getKee(), 2L));
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(singletonList(profile1)).setRuleStatus(REMOVED).build()))
+ .containsOnly(entry(profile1.getKee(), 1L));
}
@Test
- public void test_countActiveRulesForRuleStatusByProfileKey_for_a_specified_organization() {
- RuleDefinitionDto betaRule1 = db.rules().insertRule(RuleTesting.newRuleDto().setStatus(RuleStatus.BETA)).getDefinition();
- RuleDefinitionDto betaRule2 = db.rules().insertRule(RuleTesting.newRuleDto().setStatus(RuleStatus.BETA)).getDefinition();
+ public void countActiveRulesByQuery_filter_by_inheritance() {
db.qualityProfiles().activateRule(profile1, rule1);
- db.qualityProfiles().activateRule(profile2, betaRule1);
- db.qualityProfiles().activateRule(profile2, betaRule2);
-
- Map<String, Long> counts = underTest.countActiveRulesForRuleStatusByProfileUuid(dbSession, organization, RuleStatus.BETA);
-
- assertThat(counts).containsOnly(entry(profile2.getKee(), 2L));
- }
-
- @Test
- public void countActiveRulesForRuleStatusByProfileKey_returns_empty_map_if_organization_does_not_exist() {
- Map<String, Long> counts = underTest.countActiveRulesForRuleStatusByProfileUuid(dbSession, OrganizationTesting.newOrganizationDto(), RuleStatus.READY);
+ db.qualityProfiles().activateRule(profile1, rule2, ar -> ar.setInheritance(OVERRIDES));
+ db.qualityProfiles().activateRule(profile1, removedRule, ar -> ar.setInheritance(OVERRIDES));
+ db.qualityProfiles().activateRule(profile2, rule1, ar -> ar.setInheritance(OVERRIDES));
+ db.qualityProfiles().activateRule(profile2, rule2, ar -> ar.setInheritance(INHERITED));
- assertThat(counts).isEmpty();
+ ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).setInheritance(OVERRIDES).build()))
+ .containsOnly(entry(profile1.getKee(), 1L), entry(profile2.getKee(), 1L));
+ assertThat(underTest.countActiveRulesByQuery(dbSession, builder.setProfiles(asList(profile1, profile2)).setInheritance(INHERITED).build()))
+ .containsOnly(entry(profile2.getKee(), 1L));
}
@Test
- public void countActiveRulesForRuleStatusByProfileKey_returns_empty_map_if_profile_does_not_have_rules_with_specified_status() {
- Map<String, Long> counts = underTest.countActiveRulesForRuleStatusByProfileUuid(dbSession, organization, RuleStatus.DEPRECATED);
-
- assertThat(counts).isEmpty();
- }
-
- @Test
- public void test_countActiveRulesForInheritanceByProfileKey_for_a_specified_organization() {
+ public void countActiveRulesByQuery_filter_by_organization() {
db.qualityProfiles().activateRule(profile1, rule1);
- db.qualityProfiles().activateRule(profile2, rule1, ar -> ar.setInheritance(ActiveRuleDto.OVERRIDES));
- db.qualityProfiles().activateRule(profile2, rule2, ar -> ar.setInheritance(ActiveRuleDto.INHERITED));
-
- Map<String, Long> counts = underTest.countActiveRulesForInheritanceByProfileUuid(dbSession, organization, ActiveRuleDto.OVERRIDES);
-
- assertThat(counts).containsOnly(entry(profile2.getKee(), 1L));
- }
-
- @Test
- public void countActiveRulesForInheritanceByProfileKey_returns_empty_map_if_organization_does_not_exist() {
- Map<String, Long> counts = underTest.countActiveRulesForInheritanceByProfileUuid(dbSession, OrganizationTesting.newOrganizationDto(), ActiveRuleDto.OVERRIDES);
+ OrganizationDto anotherOrganization = db.organizations().insert();
+ QProfileDto profileOnAnotherOrganization = db.qualityProfiles().insert(anotherOrganization);
+ db.qualityProfiles().activateRule(profileOnAnotherOrganization, rule1);
- assertThat(counts).isEmpty();
+ assertThat(underTest.countActiveRulesByQuery(dbSession,
+ ActiveRuleCountQuery.builder().setOrganization(organization).setProfiles(asList(profile1, profileOnAnotherOrganization)).build()))
+ .containsOnly(entry(profile1.getKee(), 1L));
}
- @Test
- public void countActiveRulesForInheritanceByProfileKey_returns_empty_map_if_profile_does_not_have_rules_with_specified_status() {
- Map<String, Long> counts = underTest.countActiveRulesForInheritanceByProfileUuid(dbSession, organization, ActiveRuleDto.OVERRIDES);
-
- assertThat(counts).isEmpty();
- }
-
- @Test
- public void countActiveRulesForInheritanceByProfileKey_ignores_removed_rules() {
- db.qualityProfiles().activateRule(profile1, rule1, ar -> ar.setInheritance(ActiveRuleDto.OVERRIDES));
- db.qualityProfiles().activateRule(profile1, removedRule, ar -> ar.setInheritance(ActiveRuleDto.OVERRIDES));
-
- Map<String, Long> counts = underTest.countActiveRulesForInheritanceByProfileUuid(dbSession, organization, ActiveRuleDto.OVERRIDES);
-
- assertThat(counts).containsOnly(entry(profile1.getKee(), 1L));
- }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java
index 1dc37834cfc..cf048d75c9f 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java
@@ -19,6 +19,7 @@
*/
package org.sonar.server.qualityprofile.ws;
+import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -30,14 +31,14 @@ import org.sonar.api.server.ws.WebService.NewController;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.qualityprofile.ActiveRuleCountQuery;
import org.sonar.db.qualityprofile.ActiveRuleDao;
-import org.sonar.db.qualityprofile.ActiveRuleDto;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonarqube.ws.QualityProfiles.InheritanceWsResponse;
import org.sonarqube.ws.QualityProfiles.InheritanceWsResponse.QualityProfile;
-import static com.google.common.collect.Lists.newArrayList;
import static org.sonar.core.util.Protobuf.setNullable;
+import static org.sonar.db.qualityprofile.ActiveRuleDto.OVERRIDES;
import static org.sonar.server.qualityprofile.ws.QProfileWsSupport.createOrganizationParam;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
@@ -74,14 +75,18 @@ public class InheritanceAction implements QProfileWsAction {
OrganizationDto organization = wsSupport.getOrganization(dbSession, profile);
List<QProfileDto> ancestors = ancestors(profile, dbSession);
List<QProfileDto> children = dbClient.qualityProfileDao().selectChildren(dbSession, profile);
- Statistics statistics = new Statistics(dbSession, organization);
+ List<QProfileDto> allProfiles = new ArrayList<>();
+ allProfiles.add(profile);
+ allProfiles.addAll(ancestors);
+ allProfiles.addAll(children);
+ Statistics statistics = new Statistics(dbSession, organization, allProfiles);
writeProtobuf(buildResponse(profile, ancestors, children, statistics), request, response);
}
}
public List<QProfileDto> ancestors(QProfileDto profile, DbSession dbSession) {
- List<QProfileDto> ancestors = newArrayList();
+ List<QProfileDto> ancestors = new ArrayList<>();
collectAncestors(profile, ancestors, dbSession);
return ancestors;
}
@@ -140,10 +145,11 @@ public class InheritanceAction implements QProfileWsAction {
private final Map<String, Long> countRulesByProfileKey;
private final Map<String, Long> countOverridingRulesByProfileKey;
- private Statistics(DbSession dbSession, OrganizationDto organization) {
+ private Statistics(DbSession dbSession, OrganizationDto organization, List<QProfileDto> profiles) {
ActiveRuleDao dao = dbClient.activeRuleDao();
- countRulesByProfileKey = dao.countActiveRulesByProfileUuid(dbSession, organization);
- countOverridingRulesByProfileKey = dao.countActiveRulesForInheritanceByProfileUuid(dbSession, organization, ActiveRuleDto.OVERRIDES);
+ ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
+ countRulesByProfileKey = dao.countActiveRulesByQuery(dbSession, builder.setProfiles(profiles).build());
+ countOverridingRulesByProfileKey = dao.countActiveRulesByQuery(dbSession, builder.setProfiles(profiles).setInheritance(OVERRIDES).build());
}
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
index 866a33dc734..0600bd45062 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
@@ -33,7 +33,6 @@ import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
-import org.sonar.api.rule.RuleStatus;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
@@ -44,6 +43,7 @@ import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.qualityprofile.ActiveRuleCountQuery;
import org.sonar.db.qualityprofile.QProfileDto;
import org.sonar.server.component.ComponentFinder;
import org.sonar.server.exceptions.NotFoundException;
@@ -56,6 +56,7 @@ import org.sonarqube.ws.client.qualityprofile.SearchWsRequest;
import static com.google.common.base.Preconditions.checkState;
import static java.lang.String.format;
import static java.util.function.Function.identity;
+import static org.sonar.api.rule.RuleStatus.DEPRECATED;
import static org.sonar.api.utils.DateUtils.formatDateTime;
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
@@ -153,11 +154,14 @@ public class SearchAction implements QProfileWsAction {
List<QProfileDto> defaultProfiles = dbClient.qualityProfileDao().selectDefaultProfiles(dbSession, organization, getLanguageKeys());
List<QProfileDto> profiles = searchProfiles(dbSession, request, organization, defaultProfiles, project);
+ ActiveRuleCountQuery.Builder builder = ActiveRuleCountQuery.builder().setOrganization(organization);
return new SearchData()
.setOrganization(organization)
.setProfiles(profiles)
- .setActiveRuleCountByProfileKey(dbClient.activeRuleDao().countActiveRulesByProfileUuid(dbSession, organization))
- .setActiveDeprecatedRuleCountByProfileKey(dbClient.activeRuleDao().countActiveRulesForRuleStatusByProfileUuid(dbSession, organization, RuleStatus.DEPRECATED))
+ .setActiveRuleCountByProfileKey(
+ dbClient.activeRuleDao().countActiveRulesByQuery(dbSession, builder.setProfiles(profiles).build()))
+ .setActiveDeprecatedRuleCountByProfileKey(
+ dbClient.activeRuleDao().countActiveRulesByQuery(dbSession, builder.setProfiles(profiles).setRuleStatus(DEPRECATED).build()))
.setProjectCountByProfileKey(dbClient.qualityProfileDao().countProjectsByProfileUuid(dbSession, organization))
.setDefaultProfileKeys(defaultProfiles);
}