aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java23
-rw-r--r--server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-search.json10
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java4
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json6
-rw-r--r--sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java70
-rw-r--r--sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileProjectCount.java43
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml9
-rw-r--r--sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java10
-rw-r--r--sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml6
11 files changed, 154 insertions, 38 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java
index 9560c6b1422..8742cd7bb3b 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/QProfileSearchAction.java
@@ -28,6 +28,7 @@ import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.NewAction;
import org.sonar.api.utils.text.JsonWriter;
+import org.sonar.core.qualityprofile.db.QualityProfileDao;
import org.sonar.core.util.NonNullInputFunction;
import org.sonar.server.qualityprofile.QProfile;
import org.sonar.server.qualityprofile.QProfileLoader;
@@ -36,7 +37,11 @@ import org.sonar.server.qualityprofile.QProfileLookup;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import java.util.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
public class QProfileSearchAction implements BaseQProfileWsAction {
@@ -49,8 +54,11 @@ public class QProfileSearchAction implements BaseQProfileWsAction {
private static final String FIELD_PARENT_KEY = "parentKey";
private static final String FIELD_PARENT_NAME = "parentName";
private static final String FIELD_ACTIVE_RULE_COUNT = "activeRuleCount";
+ private static final String FIELD_PROJECT_COUNT = "projectCount";
+
private static final Set<String> ALL_FIELDS = ImmutableSet.of(
- FIELD_KEY, FIELD_NAME, FIELD_LANGUAGE, FIELD_LANGUAGE_NAME, FIELD_IS_INHERITED, FIELD_PARENT_KEY, FIELD_PARENT_NAME, FIELD_IS_DEFAULT, FIELD_ACTIVE_RULE_COUNT);
+ FIELD_KEY, FIELD_NAME, FIELD_LANGUAGE, FIELD_LANGUAGE_NAME, FIELD_IS_INHERITED, FIELD_PARENT_KEY, FIELD_PARENT_NAME, FIELD_IS_DEFAULT, FIELD_ACTIVE_RULE_COUNT,
+ FIELD_PROJECT_COUNT);
private static final String PARAM_LANGUAGE = FIELD_LANGUAGE;
private static final String PARAM_FIELDS = "f";
@@ -62,10 +70,13 @@ public class QProfileSearchAction implements BaseQProfileWsAction {
private final QProfileLoader profileLoader;
- public QProfileSearchAction(Languages languages, QProfileLookup profileLookup, QProfileLoader profileLoader) {
+ private final QualityProfileDao qualityProfileDao;
+
+ public QProfileSearchAction(Languages languages, QProfileLookup profileLookup, QProfileLoader profileLoader, QualityProfileDao qualityProfileDao) {
this.languages = languages;
this.profileLookup = profileLookup;
this.profileLoader = profileLoader;
+ this.qualityProfileDao = qualityProfileDao;
}
@Override
@@ -123,6 +134,7 @@ public class QProfileSearchAction implements BaseQProfileWsAction {
}
});
Map<String, Long> activeRuleCountByKey = profileLoader.countAllActiveRules();
+ Map<String, Long> projectCountByKey = qualityProfileDao.countProjectsByProfileKey();
json.name("profiles")
@@ -135,10 +147,15 @@ public class QProfileSearchAction implements BaseQProfileWsAction {
String key = profile.key();
Long activeRuleCount = activeRuleCountByKey.containsKey(key) ? activeRuleCountByKey.get(key) : 0L;
+ Long projectCount = projectCountByKey.containsKey(key) ? projectCountByKey.get(key) : 0L;
json.beginObject()
.prop(FIELD_KEY, nullUnlessNeeded(FIELD_KEY, key, fields))
.prop(FIELD_NAME, nullUnlessNeeded(FIELD_NAME, profile.name(), fields))
.prop(FIELD_ACTIVE_RULE_COUNT, nullUnlessNeeded(FIELD_ACTIVE_RULE_COUNT, activeRuleCount, fields));
+
+ if (!profile.isDefault()) {
+ json.prop(FIELD_PROJECT_COUNT, nullUnlessNeeded(FIELD_PROJECT_COUNT, projectCount, fields));
+ }
writeLanguageFields(json, profile, fields);
writeParentFields(json, profile, fields, profilesByKey);
// Special case for booleans
diff --git a/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-search.json b/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-search.json
index 9c796636896..1a0a85588f6 100644
--- a/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-search.json
+++ b/server/sonar-server/src/main/resources/org/sonar/server/qualityprofile/ws/example-search.json
@@ -6,7 +6,8 @@
"language": "cs",
"languageName": "C#",
"isInherited": false,
- "activeRuleCount": 37
+ "activeRuleCount": 37,
+ "isDefault": true
},
{
"key": "my-bu-profile-java-34567",
@@ -16,7 +17,9 @@
"isInherited": true,
"parentKey": "my-company-profile-java-23456",
"parentName": "My Company Profile",
- "activeRuleCount": 72
+ "activeRuleCount": 72,
+ "isDefault": false,
+ "projectCount": 13
},
{
"key": "my-company-profile-java-23456",
@@ -33,7 +36,8 @@
"language": "py",
"languageName": "Python",
"isInherited": false,
- "activeRuleCount": 125
+ "activeRuleCount": 125,
+ "isDefault": true
}
]
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java
index 4d78c497a72..6b93a45b05a 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest.java
@@ -31,6 +31,8 @@ import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.DbTester;
import org.sonar.core.qualityprofile.db.QualityProfileDao;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.server.component.ComponentTesting;
+import org.sonar.server.component.db.ComponentDao;
import org.sonar.server.db.DbClient;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.qualityprofile.QProfileLoader;
@@ -74,7 +76,7 @@ public class QProfileSearchActionTest {
mock(RuleActivationActions.class),
mock(BulkRuleActivationActions.class),
mock(ProjectAssociationActions.class),
- new QProfileSearchAction(new Languages(xoo1, xoo2), new QProfileLookup(dbClient), profileLoader)));
+ new QProfileSearchAction(new Languages(xoo1, xoo2), new QProfileLookup(dbClient), profileLoader, qualityProfileDao)));
}
@After
@@ -95,6 +97,11 @@ public class QProfileSearchActionTest {
QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2.getKey()).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456"),
QualityProfileDto.createFor("sonar-way-other-666").setLanguage("other").setName("Sonar way").setDefault(true)
);
+ new ComponentDao(mock(System2.class)).insert(session,
+ ComponentTesting.newProjectDto("project-uuid1"),
+ ComponentTesting.newProjectDto("project-uuid2"));
+ qualityProfileDao.insertProjectProfileAssociation("project-uuid1", "sonar-way-xoo2-23456", session);
+ qualityProfileDao.insertProjectProfileAssociation("project-uuid2", "sonar-way-xoo2-23456", session);
session.commit();
tester.newGetRequest("api/qualityprofiles", "search").execute().assertJson(this.getClass(), "search.json");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
index 592033e1a61..653bf535936 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
@@ -63,7 +63,7 @@ public class QProfilesWsTest {
new QProfileCreateAction(null, null, null, languages, importers),
new QProfileImportersAction(importers),
new QProfileRestoreBuiltInAction(null),
- new QProfileSearchAction(languages, null, null),
+ new QProfileSearchAction(languages, null, null, null),
new QProfileSetDefaultAction(languages, null, null),
new QProfileProjectsAction(null),
new QProfileBackupAction(null, null, null, languages),
@@ -121,7 +121,7 @@ public class QProfilesWsTest {
assertThat(search.params()).hasSize(2);
assertThat(search.param("language").possibleValues()).containsOnly(xoo1Key, xoo2Key);
assertThat(search.param("f").possibleValues())
- .containsOnly("key", "name", "language", "languageName", "isInherited", "parentKey", "parentName", "isDefault", "activeRuleCount");
+ .containsOnly("key", "name", "language", "languageName", "isInherited", "parentKey", "parentName", "isDefault", "activeRuleCount", "projectCount");
}
@Test
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json
index b800f3a3bce..6c051e7ac96 100644
--- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json
+++ b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/QProfileSearchActionTest/search.json
@@ -18,7 +18,8 @@
"isDefault": false,
"parentKey": "sonar-way-xoo2-23456",
"parentName": "Sonar way",
- "activeRuleCount": 33
+ "activeRuleCount": 33,
+ "projectCount": 0
},
{
"key": "sonar-way-xoo2-23456",
@@ -27,7 +28,8 @@
"languageName": "Xoo2",
"isInherited": false,
"isDefault": false,
- "activeRuleCount": 0
+ "activeRuleCount": 0,
+ "projectCount": 2
}
]
} \ No newline at end of file
diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java
index 81b7ddbf24b..19af5b22d78 100644
--- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileDao.java
@@ -22,6 +22,7 @@ package org.sonar.core.qualityprofile.db;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
import org.sonar.api.ServerComponent;
import org.sonar.api.utils.System2;
import org.sonar.core.component.ComponentDto;
@@ -34,6 +35,7 @@ import javax.annotation.Nullable;
import java.util.Date;
import java.util.List;
+import java.util.Map;
public class QualityProfileDao implements ServerComponent, DaoComponent {
@@ -47,7 +49,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@CheckForNull
public QualityProfileDto getByKey(DbSession session, String key) {
- return session.getMapper(QualityProfileMapper.class).selectByKey(key);
+ return getMapper(session).selectByKey(key);
}
public QualityProfileDto getNonNullByKey(DbSession session, String key) {
@@ -59,11 +61,11 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
}
public List<QualityProfileDto> findAll(DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectAll();
+ return getMapper(session).selectAll();
}
public void insert(DbSession session, QualityProfileDto profile, QualityProfileDto... otherProfiles) {
- QualityProfileMapper mapper = session.getMapper(QualityProfileMapper.class);
+ QualityProfileMapper mapper = getMapper(session);
doInsert(mapper, profile);
for (QualityProfileDto other : otherProfiles) {
doInsert(mapper, other);
@@ -93,7 +95,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
}
public void update(DbSession session, QualityProfileDto profile, QualityProfileDto... otherProfiles) {
- QualityProfileMapper mapper = session.getMapper(QualityProfileMapper.class);
+ QualityProfileMapper mapper = getMapper(session);
doUpdate(mapper, profile);
for (QualityProfileDto otherProfile : otherProfiles) {
doUpdate(mapper, otherProfile);
@@ -121,7 +123,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
}
public void delete(DbSession session, QualityProfileDto profile, QualityProfileDto... otherProfiles) {
- QualityProfileMapper mapper = session.getMapper(QualityProfileMapper.class);
+ QualityProfileMapper mapper = getMapper(session);
doDelete(mapper, profile);
for (QualityProfileDto otherProfile : otherProfiles) {
doDelete(mapper, otherProfile);
@@ -138,7 +140,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
*/
@Deprecated
public void delete(int id, DbSession session) {
- session.getMapper(QualityProfileMapper.class).delete(id);
+ getMapper(session).delete(id);
}
/**
@@ -163,7 +165,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
public List<QualityProfileDto> findAll() {
DbSession session = mybatis.openSession(false);
try {
- return session.getMapper(QualityProfileMapper.class).selectAll();
+ return getMapper(session).selectAll();
} finally {
MyBatis.closeQuietly(session);
}
@@ -171,7 +173,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@CheckForNull
public QualityProfileDto getDefaultProfile(String language, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectDefaultProfile(language);
+ return getMapper(session).selectDefaultProfile(language);
}
@CheckForNull
@@ -188,7 +190,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
public QualityProfileDto getByProjectAndLanguage(long projectId, String language) {
DbSession session = mybatis.openSession(false);
try {
- return session.getMapper(QualityProfileMapper.class).selectByProjectIdAndLanguage(projectId, language);
+ return getMapper(session).selectByProjectIdAndLanguage(projectId, language);
} finally {
MyBatis.closeQuietly(session);
}
@@ -196,13 +198,13 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@CheckForNull
public QualityProfileDto getByProjectAndLanguage(String projectKey, String language, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectByProjectAndLanguage(projectKey, language);
+ return getMapper(session).selectByProjectAndLanguage(projectKey, language);
}
public List<QualityProfileDto> findByLanguage(String language) {
DbSession session = mybatis.openSession(false);
try {
- return session.getMapper(QualityProfileMapper.class).selectByLanguage(language);
+ return getMapper(session).selectByLanguage(language);
} finally {
MyBatis.closeQuietly(session);
}
@@ -215,7 +217,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@Deprecated
@CheckForNull
public QualityProfileDto getById(int id, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectById(id);
+ return getMapper(session).selectById(id);
}
/**
@@ -235,7 +237,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@CheckForNull
public QualityProfileDto getParent(String childKey, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectParent(childKey);
+ return getMapper(session).selectParent(childKey);
}
@CheckForNull
@@ -250,7 +252,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@CheckForNull
public QualityProfileDto getParentById(int childId, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectParentById(childId);
+ return getMapper(session).selectParentById(childId);
}
@CheckForNull
@@ -264,7 +266,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
}
public List<QualityProfileDto> findChildren(DbSession session, String key) {
- return session.getMapper(QualityProfileMapper.class).selectChildren(key);
+ return getMapper(session).selectChildren(key);
}
/**
@@ -281,7 +283,7 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
@CheckForNull
public QualityProfileDto getByNameAndLanguage(String name, String language, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectByNameAndLanguage(name, language);
+ return getMapper(session).selectByNameAndLanguage(name, language);
}
/**
@@ -308,50 +310,68 @@ public class QualityProfileDao implements ServerComponent, DaoComponent {
}
public List<ComponentDto> selectProjects(String profileName, String language, DbSession session) {
- return session.getMapper(QualityProfileMapper.class).selectProjects(profileName, language);
+ return getMapper(session).selectProjects(profileName, language);
}
public int countProjects(String profileName, String language) {
DbSession session = mybatis.openSession(false);
try {
- return session.getMapper(QualityProfileMapper.class).countProjects(profileName, language);
+ return getMapper(session).countProjects(profileName, language);
+ } finally {
+ MyBatis.closeQuietly(session);
+ }
+ }
+
+ public Map<String, Long> countProjectsByProfileKey() {
+ DbSession session = mybatis.openSession(false);
+ try {
+ Map<String, Long> countByKey = Maps.newHashMap();
+ for (QualityProfileProjectCount count : getMapper(session).countProjectsByProfile()) {
+ countByKey.put(count.getProfileKey(), count.getProjectCount());
+ }
+ return countByKey;
} finally {
MyBatis.closeQuietly(session);
}
}
public void insertProjectProfileAssociation(String projectUuid, String profileKey, DbSession session) {
- session.getMapper(QualityProfileMapper.class).insertProjectProfileAssociation(projectUuid, profileKey);
+ getMapper(session).insertProjectProfileAssociation(projectUuid, profileKey);
}
public void deleteProjectProfileAssociation(String projectUuid, String profileKey, DbSession session) {
- session.getMapper(QualityProfileMapper.class).deleteProjectProfileAssociation(projectUuid, profileKey);
+ getMapper(session).deleteProjectProfileAssociation(projectUuid, profileKey);
}
public void updateProjectProfileAssociation(String projectUuid, String profileKey, DbSession session) {
- session.getMapper(QualityProfileMapper.class).updateProjectProfileAssociation(projectUuid, profileKey);
+ getMapper(session).updateProjectProfileAssociation(projectUuid, profileKey);
}
public void deleteAllProjectProfileAssociation(String profileKey, DbSession session) {
- session.getMapper(QualityProfileMapper.class).deleteAllProjectProfileAssociation(profileKey);
+ getMapper(session).deleteAllProjectProfileAssociation(profileKey);
}
public List<ProjectQprofileAssociationDto> selectSelectedProjects(String profileKey, @Nullable String query, DbSession session) {
String nameQuery = sqlQueryString(query);
- return session.getMapper(QualityProfileMapper.class).selectSelectedProjects(profileKey, nameQuery);
+ return getMapper(session).selectSelectedProjects(profileKey, nameQuery);
}
public List<ProjectQprofileAssociationDto> selectDeselectedProjects(String profileKey, @Nullable String query, DbSession session) {
String nameQuery = sqlQueryString(query);
- return session.getMapper(QualityProfileMapper.class).selectDeselectedProjects(profileKey, nameQuery);
+ return getMapper(session).selectDeselectedProjects(profileKey, nameQuery);
}
public List<ProjectQprofileAssociationDto> selectProjectAssociations(String profileKey, @Nullable String query, DbSession session) {
String nameQuery = sqlQueryString(query);
- return session.getMapper(QualityProfileMapper.class).selectProjectAssociations(profileKey, nameQuery);
+ return getMapper(session).selectProjectAssociations(profileKey, nameQuery);
}
private String sqlQueryString(String query) {
return query == null ? "%" : "%" + query.toUpperCase() + "%";
}
+
+ private QualityProfileMapper getMapper(DbSession session) {
+ return session.getMapper(QualityProfileMapper.class);
+ }
+
}
diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java
index 940c9adce99..a54a4789283 100644
--- a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java
+++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileMapper.java
@@ -67,6 +67,8 @@ public interface QualityProfileMapper {
int countProjects(@Param("profileName") String profileName, @Param("language") String language);
+ List<QualityProfileProjectCount> countProjectsByProfile();
+
QualityProfileDto selectByProjectIdAndLanguage(@Param("projectId") Long projectId, @Param("language") String language);
QualityProfileDto selectByProjectAndLanguage(@Param("projectKey") String projectKey, @Param("language") String language);
diff --git a/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileProjectCount.java b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileProjectCount.java
new file mode 100644
index 00000000000..a18bd449c8f
--- /dev/null
+++ b/sonar-core/src/main/java/org/sonar/core/qualityprofile/db/QualityProfileProjectCount.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.core.qualityprofile.db;
+
+
+public class QualityProfileProjectCount {
+
+ private String profileKey;
+ private Long projectCount;
+
+ public String getProfileKey() {
+ return profileKey;
+ }
+
+ public void setProfileKey(String profileKey) {
+ this.profileKey = profileKey;
+ }
+
+ public Long getProjectCount() {
+ return projectCount;
+ }
+
+ public void setProjectCount(Long projectCount) {
+ this.projectCount = projectCount;
+ }
+}
diff --git a/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml b/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml
index 3221d9bbf3d..9356b4f26d1 100644
--- a/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/qualityprofile/db/QualityProfileMapper.xml
@@ -151,6 +151,15 @@
</where>
</select>
+ <select id="countProjectsByProfile" resultType="org.sonar.core.qualityprofile.db.QualityProfileProjectCount">
+ SELECT pp.profile_key as profileKey, count(projects.id) as projectCount
+ FROM projects projects
+ INNER JOIN project_qprofiles pp ON pp.project_uuid=projects.uuid
+ INNER JOIN rules_profiles prof ON pp.profile_key=prof.kee
+ WHERE projects.enabled=${_true}
+ GROUP BY profileKey
+ </select>
+
<select id="selectByProjectIdAndLanguage" parameterType="map" resultType="QualityProfile">
SELECT <include refid="profilesColumns"/>
FROM rules_profiles p
diff --git a/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java b/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java
index 7518834fdd7..1839da2b120 100644
--- a/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/qualityprofile/db/QualityProfileDaoTest.java
@@ -20,6 +20,7 @@
package org.sonar.core.qualityprofile.db;
+import org.assertj.core.data.MapEntry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -226,6 +227,15 @@ public class QualityProfileDaoTest extends AbstractDaoTestCase {
}
@Test
+ public void count_projects_by_profile() {
+ setupData("projects");
+
+ assertThat(dao.countProjectsByProfileKey()).containsOnly(
+ MapEntry.entry("java_sonar_way", 2L),
+ MapEntry.entry("js_sonar_way", 2L));
+ }
+
+ @Test
public void select_by_project_id_and_language() {
setupData("projects");
diff --git a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml
index 8e6fb4c83af..94df8ad98ee 100644
--- a/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml
+++ b/sonar-core/src/test/resources/org/sonar/core/qualityprofile/db/QualityProfileDaoTest/projects.xml
@@ -5,12 +5,14 @@
<rules_profiles id="2" name="Sonar Way" language="js" parent_kee="[null]" kee="js_sonar_way" is_default="[true]"
rules_updated_at="[null]" created_at="[null]" updated_at="[null]"/>
- <projects id="1" uuid="A" kee="org.codehaus.sonar:sonar" name="SonarQube"/>
- <projects id="2" uuid="B" kee="org.codehaus.sonar-plugins.java:java" name="SonarQube Java"/>
+ <projects id="1" uuid="A" kee="org.codehaus.sonar:sonar" name="SonarQube" enabled="[true]"/>
+ <projects id="2" uuid="B" kee="org.codehaus.sonar-plugins.java:java" name="SonarQube Java" enabled="[true]"/>
+ <projects id="3" uuid="C" kee="disabled:project" name="Disabled Project" enabled="[false]"/>
<project_qprofiles id="1" project_uuid="A" profile_key="java_sonar_way"/>
<project_qprofiles id="2" project_uuid="B" profile_key="java_sonar_way"/>
<project_qprofiles id="3" project_uuid="A" profile_key="js_sonar_way"/>
<project_qprofiles id="4" project_uuid="B" profile_key="js_sonar_way"/>
+ <project_qprofiles id="5" project_uuid="C" profile_key="js_sonar_way"/>
</dataset>