--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.measure;
+
+public class LargestBranchNclocDto {
+
+ private String projectUuid;
+ private String projectName;
+ private String projectKey;
+ private long loc;
+ private String branchName;
+ private String branchType;
+ private long lastAnalysisDate;
+
+ public String getProjectUuid() {
+ return projectUuid;
+ }
+
+ public LargestBranchNclocDto setProjectUuid(String projectUuid) {
+ this.projectUuid = projectUuid;
+ return this;
+ }
+
+ public String getProjectName() {
+ return projectName;
+ }
+
+ public LargestBranchNclocDto setProjectName(String projectName) {
+ this.projectName = projectName;
+ return this;
+ }
+
+ public String getProjectKey() {
+ return projectKey;
+ }
+
+ public LargestBranchNclocDto setProjectKey(String projectKey) {
+ this.projectKey = projectKey;
+ return this;
+ }
+
+ public String getBranchName() {
+ return branchName;
+ }
+
+ public LargestBranchNclocDto setBranchName(String branchName) {
+ this.branchName = branchName;
+ return this;
+ }
+
+ public String getBranchType() {
+ return branchType;
+ }
+
+ public LargestBranchNclocDto setBranchType(String branchType) {
+ this.branchType = branchType;
+ return this;
+ }
+
+ public long getLoc() {
+ return loc;
+ }
+
+ public LargestBranchNclocDto setLoc(long loc) {
+ this.loc = loc;
+ return this;
+ }
+
+ public long getLastAnalysisDate() {
+ return lastAnalysisDate;
+ }
+
+ public LargestBranchNclocDto setLastAnalysisDate(long lastAnalysisDate) {
+ this.lastAnalysisDate = lastAnalysisDate;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder("ProjectMaxNclocDto{")
+ .append("projectUuid='").append(projectUuid).append('\'')
+ .append(", projectName='").append(projectName).append('\'')
+ .append(", projectKey='").append(projectKey).append('\'')
+ .append(", loc=").append(loc)
+ .append(", branchName='").append(branchName).append('\'')
+ .append(", branchType='").append(branchType).append('\'')
+ .append(", lastAnalysisDate=").append(lastAnalysisDate)
+ .append('}').toString();
+ }
+}
return ncloc == null ? 0L : ncloc;
}
+ public List<LargestBranchNclocDto> getLargestBranchNclocPerProject(DbSession dbSession) {
+ return mapper(dbSession).getLargestBranchNclocPerProject();
+ }
+
public long countProjectsHavingMeasure(DbSession dbSession, String metric) {
return mapper(dbSession).countProjectsHavingMeasure(metric);
}
@Param("metricKeys") Collection<String> metricKeys);
List<LiveMeasureDto> selectByComponentUuidAndMetricKeys(
- @Param("componentUuid")String componentUuid,
+ @Param("componentUuid") String componentUuid,
@Param("metricKeys") Collection<String> metricKeys);
void scrollSelectByComponentUuidAndMetricKeys(
@Param("private") Boolean privateProject,
@Nullable @Param("projectUuidToExclude") String projectUuidToExclude);
+ List<LargestBranchNclocDto> getLargestBranchNclocPerProject();
+
Long countProjectsHavingMeasure(
@Param("metric") String metric);
) sumncloc
</select>
+ <select id="getLargestBranchNclocPerProject" parameterType="map" resultType="org.sonar.db.measure.LargestBranchNclocDto">
+ select tie_breaker.projectUuid,
+ tie_breaker.projectName,
+ tie_breaker.projectKey,
+ ncloc as loc,
+ pb.kee as branchName,
+ pb.branch_type as branchType,
+ s.created_at as lastAnalysisDate
+ from
+ (select counter.projectUuid as projectUuid,
+ counter.maxncloc ncloc,
+ max(case
+ when c.main_branch_project_uuid is null
+ then 1
+ else 0
+ end) as mainBranch,
+ min(c.kee) as component_kee,
+ counter.projectName,
+ counter.projectKey
+ from
+ (select b.project_uuid as projectUuid,
+ p.name as projectName,
+ p.kee as projectKey,
+ max(lm.value) as maxncloc
+ from live_measures lm
+ inner join metrics m on m.uuid = lm.metric_uuid
+ inner join project_branches b on b.uuid = lm.component_uuid
+ inner join projects p on p.uuid = b.project_uuid and p.qualifier = 'TRK'
+ where m.name = 'ncloc'
+ group by b.project_uuid, p.name, p.kee) counter
+ inner join live_measures lmo on lmo.value = counter.maxncloc
+ inner join project_branches br on br.project_uuid = counter.projectUuid and br.uuid = lmo.component_uuid
+ inner join components c on c.uuid = br.uuid
+ group by counter.projectUuid, counter.maxncloc, counter.projectName, counter.projectKey) tie_breaker
+ inner join components c2 on c2.kee = tie_breaker.component_kee
+ inner join project_branches pb on c2.uuid = pb.uuid
+ inner join snapshots s on s.component_uuid = c2.uuid
+ where s.islast = ${_true}
+ order by ncloc desc
+ </select>
+
<select id="countProjectsHavingMeasure" parameterType="map" resultType="long">
select count(1)
from live_measures lm
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 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.measure;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LargestBranchNclocDtoTest {
+
+ private final LargestBranchNclocDto underTest = new LargestBranchNclocDto();
+
+ @Test
+ public void test_getter_and_setter() {
+ setUnderTest();
+
+ assertThat(underTest.getProjectUuid()).isEqualTo("projectUuid");
+ assertThat(underTest.getProjectName()).isEqualTo("projectName");
+ assertThat(underTest.getProjectKey()).isEqualTo("projectKey");
+ assertThat(underTest.getLoc()).isEqualTo(123L);
+ assertThat(underTest.getBranchName()).isEqualTo("branchName");
+ assertThat(underTest.getBranchType()).isEqualTo("branchType");
+ assertThat(underTest.getLastAnalysisDate()).isEqualTo(1L);
+ }
+
+ @Test
+ public void test_ToString() {
+ assertThat(new LargestBranchNclocDto())
+ .hasToString("ProjectMaxNclocDto{projectUuid='null', projectName='null', projectKey='null', loc=0, branchName='null', branchType='null', lastAnalysisDate=0}");
+ setUnderTest();
+ assertThat(underTest)
+ .hasToString(
+ "ProjectMaxNclocDto{projectUuid='projectUuid', projectName='projectName', projectKey='projectKey', loc=123, branchName='branchName', branchType='branchType', lastAnalysisDate=1}");
+ }
+
+ private void setUnderTest() {
+ underTest
+ .setProjectUuid("projectUuid")
+ .setProjectName("projectName")
+ .setProjectKey("projectKey")
+ .setLoc(123L)
+ .setBranchName("branchName")
+ .setBranchType("branchType")
+ .setLastAnalysisDate(1L);
+ }
+
+}
assertThat(result).isEqualTo(10L + 200L);
}
+ @Test
+ public void get_branch_with_max_ncloc_per_project() {
+ SetupProjectsWithLoc();
+
+ List<LargestBranchNclocDto> results = underTest.getLargestBranchNclocPerProject(db.getSession());
+
+ assertThat(results).hasSize(5);
+ assertLocForProject(results.get(0), "projectWithTieOnBranchSize", "master", 250);
+ assertLocForProject(results.get(1), "projectWithTieOnOtherBranches", "tieBranch1", 230);
+ assertLocForProject(results.get(2), "projectWithBranchBiggerThanMaster", "notMasterBranch", 200);
+ assertLocForProject(results.get(3), "simpleProject", "master", 10);
+ assertLocForProject(results.get(4), "projectWithLinesButNoLoc", "master", 0);
+ }
+
@Test
public void countNcloc_empty() {
db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
// do not compare the field "uuid", which is used only for insert, not select
"componentUuid", "projectUuid", "metricUuid", "value", "textValue", "data", "variation");
}
+
+ private void SetupProjectsWithLoc() {
+ MetricDto ncloc = db.measures().insertMetric(m -> m.setKey("ncloc").setValueType(INT.toString()));
+ MetricDto lines = db.measures().insertMetric(m -> m.setKey("lines").setValueType(INT.toString()));
+
+ addProjectWithMeasure("simpleProject", ncloc, 10d);
+
+ ComponentDto projectWithBranchBiggerThanMaster = addProjectWithMeasure("projectWithBranchBiggerThanMaster", ncloc, 100d);
+ addBranchToProjectWithMeasure(projectWithBranchBiggerThanMaster,"notMasterBranch", ncloc, 200d);
+
+ ComponentDto projectWithLinesButNoLoc = addProjectWithMeasure("projectWithLinesButNoLoc", lines, 365d);
+ addMeasureToComponent(projectWithLinesButNoLoc,ncloc,0d,false);
+
+ ComponentDto projectWithTieOnBranchSize = addProjectWithMeasure("projectWithTieOnBranchSize", ncloc, 250d);
+ addBranchToProjectWithMeasure(projectWithTieOnBranchSize,"tieBranch", ncloc, 250d);
+
+ ComponentDto projectWithTieOnOtherBranches = addProjectWithMeasure("projectWithTieOnOtherBranches", ncloc, 220d);
+ addBranchToProjectWithMeasure(projectWithTieOnOtherBranches,"tieBranch1", ncloc, 230d);
+ addBranchToProjectWithMeasure(projectWithTieOnOtherBranches,"tieBranch2", ncloc, 230d);
+ }
+
+ private ComponentDto addProjectWithMeasure(String projectKey, MetricDto metric, double metricValue) {
+ ComponentDto project = db.components().insertPublicProject(p -> p.setDbKey(projectKey));
+ addMeasureToComponent(project, metric, metricValue,true);
+ return project;
+ }
+
+ private void addMeasureToComponent(ComponentDto component, MetricDto metric, double metricValue, boolean addSnapshot) {
+ db.measures().insertLiveMeasure(component, metric, m -> m.setValue(metricValue));
+ if (addSnapshot) {
+ db.components().insertSnapshot(component, t -> t.setLast(true));
+ }
+ }
+
+ private void addBranchToProjectWithMeasure(ComponentDto project, String branchKey, MetricDto metric, double metricValue) {
+ ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.BRANCH).setKey(branchKey));
+ addMeasureToComponent(branch, metric, metricValue,true);
+ }
+
+ private void assertLocForProject(LargestBranchNclocDto result, String projectKey, String branchKey, long linesOfCode) {
+ assertThat(result.getProjectKey()).isEqualTo(projectKey);
+ assertThat(result.getBranchName()).isEqualTo(branchKey);
+ assertThat(result.getLoc()).isEqualTo(linesOfCode);
+ }
}