]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16075 create DAO method for retrieving biggest branch per project
authorMatteo Mara <matteo.mara@sonarsource.com>
Thu, 3 Mar 2022 10:39:12 +0000 (11:39 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 9 Mar 2022 20:02:58 +0000 (20:02 +0000)
server/sonar-db-dao/src/main/java/org/sonar/db/measure/LargestBranchNclocDto.java [new file with mode: 0644]
server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/measure/LargestBranchNclocDtoTest.java [new file with mode: 0644]
server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java

diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LargestBranchNclocDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LargestBranchNclocDto.java
new file mode 100644 (file)
index 0000000..ae9728f
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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();
+  }
+}
index feb2d1ec337ac1d60330e99062a6c410a26e9ae6..3b1659aaa95c77b6070e5c05c650f7d6f43eb6a9 100644 (file)
@@ -102,6 +102,10 @@ public class LiveMeasureDao implements Dao {
     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);
   }
index ac75f35d9c7421410a98fa77cc5c7bf507218b7f..8bf20c4a17dfb2f0a4a5959847affd6cc87b960d 100644 (file)
@@ -36,7 +36,7 @@ public interface LiveMeasureMapper {
     @Param("metricKeys") Collection<String> metricKeys);
 
   List<LiveMeasureDto> selectByComponentUuidAndMetricKeys(
-    @Param("componentUuid")String componentUuid,
+    @Param("componentUuid") String componentUuid,
     @Param("metricKeys") Collection<String> metricKeys);
 
   void scrollSelectByComponentUuidAndMetricKeys(
@@ -59,6 +59,8 @@ public interface LiveMeasureMapper {
     @Param("private") Boolean privateProject,
     @Nullable @Param("projectUuidToExclude") String projectUuidToExclude);
 
+  List<LargestBranchNclocDto> getLargestBranchNclocPerProject();
+
   Long countProjectsHavingMeasure(
     @Param("metric") String metric);
 
index 2141836ab7fdc6f109e28b1e99019e3d100f7011..3fe2bcd3fc5b3ec9047d60b63414c15c958b0996 100644 (file)
     ) 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
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/LargestBranchNclocDtoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/LargestBranchNclocDtoTest.java
new file mode 100644 (file)
index 0000000..f3d8d9a
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * 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);
+  }
+
+}
index bcf6a7de161f46a1a49f37accf9850bb36ae9a6c..36bbb9a8b6dc8609055cc20a62248d8648a19950 100644 (file)
@@ -325,6 +325,20 @@ public class LiveMeasureDaoTest {
     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()));
@@ -685,4 +699,48 @@ public class LiveMeasureDaoTest {
       // 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);
+  }
 }