]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9482 Use query object to count active rules in db
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 29 Jun 2017 08:42:55 +0000 (10:42 +0200)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 4 Jul 2017 14:29:36 +0000 (16:29 +0200)
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleCountQuery.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/ActiveRuleMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/ActiveRuleMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/qualityprofile/ActiveRuleDaoTest.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/InheritanceAction.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java

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 (file)
index 0000000..02303b9
--- /dev/null
@@ -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);
+    }
+  }
+
+}
index e62d881de6db5c269fe8ea536c2da5d847a82da7..a699eab78707de55cffa8c78fd063620353fa047 100644 (file)
@@ -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) {
index 5c384a20ccd331fc18817bae84e0890b344c42d2..6a64c21ee4ebdf4387b6dbb46d4ca64d689ab90e 100644 (file)
@@ -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);
 }
index 840467e7e8b46bfa67e45fe6b8a5694556b2ebc8..29ac1dc74812a28816d47e63faa112614f9268ad 100644 (file)
     </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>
 
index 62c4c989d775c9ae902c45965c4fe7130b254284..8eb040b9d0bfdaf34e441db5882c47966fabf94e 100644 (file)
  */
 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));
-  }
 }
index 1dc37834cfc0a348a7bf6ca67d57a443a2920b32..cf048d75c9fd2468e171bf75e23811e8d6706fa8 100644 (file)
@@ -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());
     }
   }
 }
index 866a33dc734ac7ac2d506409ec65db377033016c..0600bd45062fbce9a39fdc85e2ff3c357020023a 100644 (file)
@@ -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);
     }