aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorDuarte Meneses <duarte.meneses@sonarsource.com>2020-03-23 19:21:34 -0500
committersonartech <sonartech@sonarsource.com>2020-03-30 20:03:43 +0000
commit88597f3717a873db1373e4d4b2bcca7f5fd74425 (patch)
treec546b1449a8997d55c1fe18442013d1f09f06ba8 /server
parent9ea4d1c0a65d82acd4c4d3628a82b6a673fcb0c9 (diff)
downloadsonarqube-88597f3717a873db1373e4d4b2bcca7f5fd74425.tar.gz
sonarqube-88597f3717a873db1373e4d4b2bcca7f5fd74425.zip
SONAR-12691 Refactor measures DAO
Diffstat (limited to 'server')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java18
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java6
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java38
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java6
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java226
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml8
-rw-r--r--server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml53
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java39
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java120
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureQueryTest.java131
10 files changed, 112 insertions, 533 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java
index 5d8a15e184f..a28d7f829ec 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java
@@ -33,7 +33,6 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.KeyType;
import org.sonar.db.dialect.Dialect;
-import static java.util.Collections.singletonList;
import static org.sonar.api.measures.CoreMetrics.NCLOC_KEY;
import static org.sonar.db.DatabaseUtils.executeLargeInputs;
@@ -74,18 +73,17 @@ public class LiveMeasureDao implements Dao {
componentUuids -> mapper(dbSession).selectByComponentUuidsAndMetricKeys(componentUuids, metricKeys));
}
- public Optional<LiveMeasureDto> selectByComponentUuidAndMetricKey(DbSession dbSession, String componentUuid, String metricKey) {
- LiveMeasureDto liveMeasureDto = mapper(dbSession).selectByComponentUuidAndMetricKey(componentUuid, metricKey);
- return Optional.ofNullable(liveMeasureDto);
+ public List<LiveMeasureDto> selectByComponentUuidAndMetricKeys(DbSession dbSession, String componentUuid, Collection<String> metricKeys) {
+ if (metricKeys.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ return mapper(dbSession).selectByComponentUuidAndMetricKeys(componentUuid, metricKeys);
}
public Optional<LiveMeasureDto> selectMeasure(DbSession dbSession, String componentUuid, String metricKey) {
- List<LiveMeasureDto> measures = selectByComponentUuidsAndMetricKeys(dbSession, singletonList(componentUuid), singletonList(metricKey));
- // couple of columns [component_uuid, metric_id] is unique. List can't have more than 1 item.
- if (measures.size() == 1) {
- return Optional.of(measures.get(0));
- }
- return Optional.empty();
+ LiveMeasureDto liveMeasureDto = mapper(dbSession).selectByComponentUuidAndMetricKey(componentUuid, metricKey);
+ return Optional.ofNullable(liveMeasureDto);
}
public void selectTreeByQuery(DbSession dbSession, ComponentDto baseComponent, MeasureTreeQuery query, ResultHandler<LiveMeasureDto> resultHandler) {
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java
index a31b0051cf1..3b26e2fdbcc 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java
@@ -21,11 +21,9 @@ package org.sonar.db.measure;
import java.util.Collection;
import java.util.List;
-import java.util.Set;
import javax.annotation.Nullable;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler;
-import org.sonar.db.DbSession;
import org.sonar.db.component.BranchType;
import org.sonar.db.component.KeyType;
@@ -39,6 +37,10 @@ public interface LiveMeasureMapper {
@Param("componentUuids") Collection<String> componentUuids,
@Param("metricKeys") Collection<String> metricKeys);
+ List<LiveMeasureDto> selectByComponentUuidAndMetricKeys(
+ @Param("componentUuid")String componentUuid,
+ @Param("metricKeys") Collection<String> metricKeys);
+
void scrollSelectByComponentUuidAndMetricKeys(
@Param("componentUuid") String componentUuid,
@Param("metricKeys") Collection<String> metricKeys,
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java
index c27e4d0d835..2420349129e 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java
@@ -26,9 +26,6 @@ import java.util.Optional;
import org.sonar.db.Dao;
import org.sonar.db.DbSession;
-import static java.util.Collections.emptyList;
-import static org.sonar.db.DatabaseUtils.executeLargeInputs;
-
public class MeasureDao implements Dao {
public Optional<MeasureDto> selectLastMeasure(DbSession dbSession, String componentUuid, String metricKey) {
@@ -40,41 +37,6 @@ public class MeasureDao implements Dao {
}
/**
- * Selects the measures of either the last analysis (when {@link MeasureQuery#analysisUuid} is {@code null}) or of the
- * specified analysis (given by {@link MeasureQuery#analysisUuid}).
- * The components can be specified either as :
- * - A list of projects in {@link MeasureQuery#projectUuids}
- * - A list of components in {@link MeasureQuery#componentUuids} with one mandatory project in {@link MeasureQuery#projectUuids}
- * - One single component in {@link MeasureQuery#componentUuids}
- * <p>
- * Returned measure can optionally be filtered metric (either by specifying {@link MeasureQuery#metricIds}
- * or {@link MeasureQuery#metricKeys}).
- * </p>
- */
- public List<MeasureDto> selectByQuery(DbSession dbSession, MeasureQuery query) {
- if (query.returnsEmpty()) {
- return emptyList();
- }
- if (query.isOnComponents()) {
- return executeLargeInputs(
- query.getComponentUuids(),
- componentUuids -> {
- MeasureQuery pageQuery = MeasureQuery.copyWithSubsetOfComponentUuids(query, componentUuids);
- return mapper(dbSession).selectByQueryOnComponents(pageQuery);
- });
- }
- if (query.isOnProjects()) {
- return executeLargeInputs(
- query.getProjectUuids(),
- projectUuids -> {
- MeasureQuery pageQuery = MeasureQuery.copyWithSubsetOfProjectUuids(query, projectUuids);
- return mapper(dbSession).selectByQueryOnProjects(pageQuery);
- });
- }
- return mapper(dbSession).selectByQueryOnSingleComponent(query);
- }
-
- /**
* Select measures of:
* - one component
* - for a list of metrics
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java
index 5892ec457b0..d31e336b1d8 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java
@@ -38,12 +38,6 @@ public interface MeasureMapper {
@Param("metricKey") String metricKey
);
- List<MeasureDto> selectByQueryOnProjects(@Param("query") MeasureQuery query);
-
- List<MeasureDto> selectByQueryOnComponents(@Param("query") MeasureQuery query);
-
- List<MeasureDto> selectByQueryOnSingleComponent(@Param("query") MeasureQuery query);
-
List<MeasureDto> selectPastMeasuresOnSeveralAnalyses(@Param("query") PastMeasureQuery query);
void insert(MeasureDto measureDto);
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java
deleted file mode 100644
index 7113fca91ac..00000000000
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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 java.util.Collection;
-import java.util.Objects;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static java.util.Collections.singleton;
-import static java.util.Objects.requireNonNull;
-
-public class MeasureQuery {
- @CheckForNull
- private final String analysisUuid;
-
- @CheckForNull
- private final Collection<String> projectUuids;
-
- @CheckForNull
- private final Collection<String> componentUuids;
-
- @CheckForNull
- private final Collection<Integer> metricIds;
-
- @CheckForNull
- private final Collection<String> metricKeys;
-
- private MeasureQuery(Builder builder) {
- this(builder.analysisUuid, builder.projectUuids, builder.componentUuids, builder.metricIds, builder.metricKeys);
- }
-
- private MeasureQuery(@Nullable String analysisUuid,
- @Nullable Collection<String> projectUuids,
- @Nullable Collection<String> componentUuids,
- @Nullable Collection<Integer> metricIds,
- @Nullable Collection<String> metricKeys) {
- checkArgument(metricIds == null || metricKeys == null, "Metric IDs and keys must not be set both");
- checkArgument(projectUuids != null || componentUuids != null, "At least one filter on component UUID is expected");
- checkArgument(componentUuids == null || componentUuids.size() == 1 || (projectUuids != null && projectUuids.size() == 1),
- "Component UUIDs can only be used when a single project UUID is set");
-
- this.analysisUuid = analysisUuid;
- this.projectUuids = projectUuids;
- this.componentUuids = componentUuids;
- this.metricIds = metricIds;
- this.metricKeys = metricKeys;
- }
-
- @CheckForNull
- public String getAnalysisUuid() {
- return analysisUuid;
- }
-
- @CheckForNull
- public Collection<String> getProjectUuids() {
- return projectUuids;
- }
-
- @CheckForNull
- public String getProjectUuid() {
- return isOnComponents() ? projectUuids.iterator().next() : null;
- }
-
- @CheckForNull
- public Collection<String> getComponentUuids() {
- return componentUuids;
- }
-
- @CheckForNull
- public String getComponentUuid() {
- return isOnSingleComponent() ? componentUuids.iterator().next() : null;
- }
-
- @CheckForNull
- public Collection<Integer> getMetricIds() {
- return metricIds;
- }
-
- @CheckForNull
- public Collection<String> getMetricKeys() {
- return metricKeys;
- }
-
- public boolean returnsEmpty() {
- return (projectUuids != null && projectUuids.isEmpty())
- || (componentUuids != null && componentUuids.isEmpty())
- || (metricIds != null && metricIds.isEmpty())
- || (metricKeys != null && metricKeys.isEmpty());
- }
-
- public boolean isOnProjects() {
- return projectUuids != null && componentUuids == null;
- }
-
- public boolean isOnComponents() {
- return projectUuids != null && projectUuids.size() == 1 && componentUuids != null;
- }
-
- public boolean isOnSingleComponent() {
- return projectUuids == null && componentUuids != null && componentUuids.size() == 1;
- }
-
- @Override
- public boolean equals(@Nullable Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- MeasureQuery that = (MeasureQuery) o;
- return Objects.equals(analysisUuid, that.analysisUuid) &&
- Objects.equals(projectUuids, that.projectUuids) &&
- Objects.equals(componentUuids, that.componentUuids) &&
- Objects.equals(metricIds, that.metricIds) &&
- Objects.equals(metricKeys, that.metricKeys);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(analysisUuid, componentUuids, metricIds, metricKeys);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- static MeasureQuery copyWithSubsetOfProjectUuids(MeasureQuery query, Collection<String> projectUuids) {
- return new MeasureQuery(query.analysisUuid, projectUuids, query.componentUuids, query.metricIds, query.metricKeys);
- }
-
- static MeasureQuery copyWithSubsetOfComponentUuids(MeasureQuery query, Collection<String> componentUuids) {
- return new MeasureQuery(query.analysisUuid, query.projectUuids, componentUuids, query.metricIds, query.metricKeys);
- }
-
- public static final class Builder {
- private String analysisUuid;
- private Collection<String> projectUuids;
- private Collection<String> componentUuids;
- private Collection<Integer> metricIds;
- private Collection<String> metricKeys;
-
- private Builder() {
- // see MeasureQuery#builder()
- }
-
- public Builder setAnalysisUuid(String analysisUuid) {
- this.analysisUuid = analysisUuid;
- return this;
- }
-
- /**
- * List of projects
- */
- public Builder setProjectUuids(@Nullable Collection<String> projectUuids) {
- this.projectUuids = projectUuids;
- return this;
- }
-
- /**
- * List of components of a project
- */
- public Builder setComponentUuids(String projectUuid, Collection<String> componentUuids) {
- setProjectUuids(singleton(requireNonNull(projectUuid)));
- this.componentUuids = componentUuids;
- return this;
- }
-
- /**
- * Single component
- */
- public Builder setComponentUuid(String componentUuid) {
- this.componentUuids = singleton(componentUuid);
- return this;
- }
-
- /**
- * All the measures are returned if parameter is {@code null}.
- */
- public Builder setMetricIds(@Nullable Collection<Integer> metricIds) {
- this.metricIds = metricIds;
- return this;
- }
-
- public Builder setMetricId(int metricId) {
- this.metricIds = singleton(metricId);
- return this;
- }
-
- /**
- * All the measures are returned if parameter is {@code null}.
- */
- public Builder setMetricKeys(@Nullable Collection<String> s) {
- this.metricKeys = s;
- return this;
- }
-
- public Builder setMetricKey(String s) {
- this.metricKeys = singleton(s);
- return this;
- }
-
- public MeasureQuery build() {
- return new MeasureQuery(this);
- }
- }
-}
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml
index 2a7075dcea9..cbc469e82db 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/LiveMeasureMapper.xml
@@ -34,6 +34,14 @@
</foreach>
</select>
+ <select id="selectByComponentUuidAndMetricKeys" parameterType="map" resultType="org.sonar.db.measure.LiveMeasureDto">
+ select <include refid="columns"/> from live_measures lm
+ inner join metrics m on m.id = lm.metric_id
+ where
+ m.name in <foreach item="metricKey" collection="metricKeys" open="(" separator="," close=")">#{metricKey, jdbcType=VARCHAR}</foreach>
+ and lm.component_uuid = #{componentUuid, jdbcType=VARCHAR}
+ </select>
+
<select id="selectByComponentUuidAndMetricKey" parameterType="map" resultType="org.sonar.db.measure.LiveMeasureDto">
select <include refid="columns"/> from live_measures lm
inner join metrics m on m.id = lm.metric_id
diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml
index dafc59b1939..acdb80d718c 100644
--- a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml
+++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml
@@ -37,40 +37,6 @@
s.uuid = #{analysisUuid,jdbcType=VARCHAR}
</select>
- <select id="selectByQueryOnProjects" parameterType="map" resultType="Measure">
- select <include refid="measureColumns"/> from project_measures pm
- <include refid="selectByQueryCommonJoins"/>
- where
- <include refid="selectByQueryCommonFilters"/>
- and analysis.component_uuid=pm.component_uuid
- and analysis.component_uuid in
- <foreach item="projectUuid" collection="query.getProjectUuids()" open="(" separator="," close=")">
- #{projectUuid,jdbcType=VARCHAR}
- </foreach>
- </select>
-
- <select id="selectByQueryOnComponents" parameterType="map" resultType="Measure">
- select <include refid="measureColumns"/> from project_measures pm
- <include refid="selectByQueryCommonJoins"/>
- where
- <include refid="selectByQueryCommonFilters"/>
- and analysis.component_uuid=#{query.projectUuid,jdbcType=VARCHAR}
- and pm.component_uuid in
- <foreach item="componentUuid" collection="query.getComponentUuids()" open="(" separator="," close=")">
- #{componentUuid,jdbcType=VARCHAR}
- </foreach>
- </select>
-
- <select id="selectByQueryOnSingleComponent" parameterType="map" resultType="Measure">
- select <include refid="measureColumns"/> from project_measures pm
- <include refid="selectByQueryCommonJoins"/>
- inner join components p on p.project_uuid=analysis.component_uuid
- and p.uuid=pm.component_uuid
- where
- <include refid="selectByQueryCommonFilters"/>
- and pm.component_uuid=#{query.componentUuid,jdbcType=VARCHAR}
- </select>
-
<sql id="selectByQueryCommonJoins">
inner join snapshots analysis on analysis.uuid = pm.analysis_uuid
<if test="query.getMetricKeys() != null">
@@ -78,25 +44,6 @@
</if>
</sql>
- <sql id="selectByQueryCommonFilters">
- <if test="query.getAnalysisUuid() == null">
- analysis.islast=${_true}
- </if>
- <if test="query.getAnalysisUuid() != null">
- analysis.uuid = #{query.analysisUuid,jdbcType=VARCHAR}
- </if>
- <if test="query.getMetricIds() != null">
- and pm.metric_id in
- <foreach item="metricId" collection="query.getMetricIds()" open="(" separator="," close=")">#{metricId}</foreach>
- </if>
- <if test="query.getMetricKeys() != null">
- and m.name in
- <foreach item="metricKey" collection="query.getMetricKeys()" open="(" separator="," close=")">
- #{metricKey,jdbcType=VARCHAR}
- </foreach>
- </if>
- </sql>
-
<select id="selectPastMeasuresOnSeveralAnalyses" parameterType="map" resultType="Measure">
select <include refid="measureColumns"/>
from project_measures pm
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java
index 6c53f9d82e7..5b0acf9ca51 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/LiveMeasureDaoTest.java
@@ -146,7 +146,7 @@ public class LiveMeasureDaoTest {
LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
underTest.insert(db.getSession(), measure);
- Optional<LiveMeasureDto> selected = underTest.selectByComponentUuidAndMetricKey(db.getSession(), measure.getComponentUuid(), metric.getKey());
+ Optional<LiveMeasureDto> selected = underTest.selectMeasure(db.getSession(), measure.getComponentUuid(), metric.getKey());
assertThat(selected).isNotEmpty();
assertThat(selected.get()).isEqualToComparingFieldByField(measure);
@@ -157,7 +157,7 @@ public class LiveMeasureDaoTest {
LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
underTest.insert(db.getSession(), measure);
- assertThat(underTest.selectByComponentUuidAndMetricKey(db.getSession(), "_missing_", metric.getKey())).isEmpty();
+ assertThat(underTest.selectMeasure(db.getSession(), "_missing_", metric.getKey())).isEmpty();
}
@Test
@@ -165,7 +165,40 @@ public class LiveMeasureDaoTest {
LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
underTest.insert(db.getSession(), measure);
- assertThat(underTest.selectByComponentUuidAndMetricKey(db.getSession(), measure.getComponentUuid(), "_missing_")).isEmpty();
+ assertThat(underTest.selectMeasure(db.getSession(), measure.getComponentUuid(), "_missing_")).isEmpty();
+ }
+
+ @Test
+ public void selectByComponentUuidAndMetricKeys() {
+ MetricDto metric2 = db.measures().insertMetric();
+
+ LiveMeasureDto measure1 = newLiveMeasure().setMetricId(metric.getId()).setValue(1.0).setComponentUuid("uuid");
+ LiveMeasureDto measure2 = newLiveMeasure().setMetricId(metric2.getId()).setValue(2.0).setComponentUuid("uuid");
+
+ underTest.insert(db.getSession(), measure1);
+ underTest.insert(db.getSession(), measure2);
+
+ List<LiveMeasureDto> selected = underTest.selectByComponentUuidAndMetricKeys(db.getSession(), "uuid", asList(metric.getKey(), metric2.getKey()));
+
+ assertThat(selected).hasSize(2);
+ assertThat(selected).extracting(LiveMeasureDto::getMetricId, LiveMeasureDto::getValue)
+ .containsExactlyInAnyOrder(tuple(metric.getId(), measure1.getValue()), tuple(metric2.getId(), measure2.getValue()));
+ }
+
+ @Test
+ public void selectByComponentUuidAndMetricKeys_return_empty_if_component_does_not_match() {
+ LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
+ underTest.insert(db.getSession(), measure);
+
+ assertThat(underTest.selectByComponentUuidAndMetricKeys(db.getSession(), "_missing_", singletonList(metric.getKey()))).isEmpty();
+ }
+
+ @Test
+ public void selectByComponentUuidAndMetricKeys_return_empty_if_no_metric_matches() {
+ LiveMeasureDto measure = newLiveMeasure().setMetricId(metric.getId());
+ underTest.insert(db.getSession(), measure);
+
+ assertThat(underTest.selectByComponentUuidAndMetricKeys(db.getSession(), measure.getComponentUuid(), singletonList("_missing_"))).isEmpty();
}
@Test
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java
index e0a2a6514f5..834d0927f18 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureDaoTest.java
@@ -20,6 +20,8 @@
package org.sonar.db.measure;
import java.util.List;
+import java.util.Optional;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -33,8 +35,6 @@ import org.sonar.db.component.SnapshotDto;
import org.sonar.db.component.SnapshotTesting;
import org.sonar.db.metric.MetricDto;
-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.sonar.api.utils.DateUtils.parseDate;
@@ -44,9 +44,9 @@ import static org.sonar.db.component.SnapshotTesting.newAnalysis;
public class MeasureDaoTest {
- private static final int COVERAGE_METRIC_ID = 10;
- private static final int COMPLEXITY_METRIC_ID = 11;
- private static final int NCLOC_METRIC_ID = 12;
+ private MetricDto coverage;
+ private MetricDto complexity;
+ private MetricDto ncloc;
@Rule
public ExpectedException expectedException = ExpectedException.none();
@@ -58,6 +58,13 @@ public class MeasureDaoTest {
private MeasureDao underTest = db.getDbClient().measureDao();
+ @Before
+ public void before() {
+ coverage =db.measures().insertMetric(m -> m.setKey("coverage"));
+ complexity = db.measures().insertMetric(m -> m.setKey( "complexity"));
+ ncloc = db.measures().insertMetric(m -> m.setKey("ncloc"));
+ }
+
@Test
public void test_selectLastMeasure() {
MetricDto metric = db.measures().insertMetric();
@@ -104,7 +111,7 @@ public class MeasureDaoTest {
}
@Test
- public void selectByQuery() {
+ public void test_selects() {
ComponentDto project1 = db.components().insertPrivateProject();
ComponentDto module = db.components().insertComponent(newModuleDto(project1));
db.components().insertComponent(newFileDto(module).setUuid("C1"));
@@ -116,69 +123,45 @@ public class MeasureDaoTest {
SnapshotDto project2LastAnalysis = insertAnalysis(project2.uuid(), true);
// project 1
- insertMeasure("P1_M1", lastAnalysis.getUuid(), project1.uuid(), NCLOC_METRIC_ID);
- insertMeasure("P1_M2", lastAnalysis.getUuid(), project1.uuid(), COVERAGE_METRIC_ID);
- insertMeasure("P1_M3", pastAnalysis.getUuid(), project1.uuid(), NCLOC_METRIC_ID);
+ insertMeasure("P1_M1", lastAnalysis.getUuid(), project1.uuid(), ncloc.getId());
+ insertMeasure("P1_M2", lastAnalysis.getUuid(), project1.uuid(), coverage.getId());
+ insertMeasure("P1_M3", pastAnalysis.getUuid(), project1.uuid(), ncloc.getId());
// project 2
- insertMeasure("P2_M1", project2LastAnalysis.getUuid(), project2.uuid(), NCLOC_METRIC_ID);
- insertMeasure("P2_M2", project2LastAnalysis.getUuid(), project2.uuid(), COVERAGE_METRIC_ID);
+ insertMeasure("P2_M1", project2LastAnalysis.getUuid(), project2.uuid(), ncloc.getId());
+ insertMeasure("P2_M2", project2LastAnalysis.getUuid(), project2.uuid(), coverage.getId());
// component C1
- insertMeasure("M1", pastAnalysis.getUuid(), "C1", NCLOC_METRIC_ID);
- insertMeasure("M2", lastAnalysis.getUuid(), "C1", NCLOC_METRIC_ID);
- insertMeasure("M3", lastAnalysis.getUuid(), "C1", COVERAGE_METRIC_ID);
+ insertMeasure("M1", pastAnalysis.getUuid(), "C1", ncloc.getId());
+ insertMeasure("M2", lastAnalysis.getUuid(), "C1", ncloc.getId());
+ insertMeasure("M3", lastAnalysis.getUuid(), "C1", coverage.getId());
// component C2
- insertMeasure("M6", lastAnalysis.getUuid(), "C2", NCLOC_METRIC_ID);
+ insertMeasure("M6", lastAnalysis.getUuid(), "C2", ncloc.getId());
db.commit();
- verifyZeroMeasures(MeasureQuery.builder().setComponentUuids(project1.uuid(), emptyList()));
- verifyZeroMeasures(MeasureQuery.builder().setComponentUuid("MISSING_COMPONENT"));
- verifyZeroMeasures(MeasureQuery.builder().setProjectUuids(emptyList()));
- verifyZeroMeasures(MeasureQuery.builder().setProjectUuids(singletonList("MISSING_COMPONENT")));
-
- // all measures of component C1 of last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1"), "M2", "M3");
- // all measures of component C1 of non last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(pastAnalysis.getUuid()), "M1");
- // all measures of component C1 of last analysis by UUID
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(lastAnalysis.getUuid()), "M2", "M3");
+ verifyNoMeasure("C1", ncloc.getKey(), "invalid_analysis");
+ verifyNoMeasure("C1", "INVALID_KEY");
+ verifyNoMeasure("C1", "INVALID_KEY", pastAnalysis.getUuid());
+ verifyNoMeasure("MISSING_COMPONENT", ncloc.getKey());
+ verifyNoMeasure("MISSING_COMPONENT", ncloc.getKey(), pastAnalysis.getUuid());
// ncloc measure of component C1 of last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setMetricId(NCLOC_METRIC_ID), "M2");
+ verifyMeasure("C1", ncloc.getKey(), "M2");
// ncloc measure of component C1 of non last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(pastAnalysis.getUuid()).setMetricId(NCLOC_METRIC_ID), "M1");
+ verifyMeasure("C1", ncloc.getKey(), pastAnalysis.getUuid(), "M1");
// ncloc measure of component C1 of last analysis by UUID
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(lastAnalysis.getUuid()).setMetricId(NCLOC_METRIC_ID), "M2");
-
- // multiple measures of component C1 of last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setMetricIds(asList(NCLOC_METRIC_ID, COVERAGE_METRIC_ID)), "M2", "M3");
- // multiple measures of component C1 of non last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(pastAnalysis.getUuid()).setMetricIds(asList(NCLOC_METRIC_ID, COVERAGE_METRIC_ID)), "M1");
- // multiple measures of component C1 of last analysis by UUID
- verifyMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(lastAnalysis.getUuid()).setMetricIds(asList(NCLOC_METRIC_ID, COVERAGE_METRIC_ID)), "M2", "M3");
+ verifyMeasure("C1", ncloc.getKey(), lastAnalysis.getUuid(), "M2");
// missing measure of component C1 of last analysis
- verifyZeroMeasures(MeasureQuery.builder().setComponentUuid("C1").setMetricId(COMPLEXITY_METRIC_ID));
+ verifyNoMeasure("C1", complexity.getKey());
// missing measure of component C1 of non last analysis
- verifyZeroMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(pastAnalysis.getUuid()).setMetricId(COMPLEXITY_METRIC_ID));
+ verifyNoMeasure("C1", complexity.getKey(), pastAnalysis.getUuid());
// missing measure of component C1 of last analysis by UUID
- verifyZeroMeasures(MeasureQuery.builder().setComponentUuid("C1").setAnalysisUuid(lastAnalysis.getUuid()).setMetricId(COMPLEXITY_METRIC_ID));
-
- // ncloc measures of components C1, C2 and C3 (which does not exist) of last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuids(project1.uuid(), asList("C1", "C2", "C3")), "M2", "M3", "M6");
- // ncloc measures of components C1, C2 and C3 (which does not exist) of non last analysis
- verifyMeasures(MeasureQuery.builder().setComponentUuids(project1.uuid(), asList("C1", "C2", "C3")).setAnalysisUuid(pastAnalysis.getUuid()), "M1");
- // ncloc measures of components C1, C2 and C3 (which does not exist) of last analysis by UUID
- verifyMeasures(MeasureQuery.builder().setComponentUuids(project1.uuid(), asList("C1", "C2", "C3")).setAnalysisUuid(lastAnalysis.getUuid()), "M2", "M3", "M6");
+ verifyNoMeasure("C1", complexity.getKey(), lastAnalysis.getUuid());
// projects measures of last analysis
- verifyMeasures(MeasureQuery.builder().setProjectUuids(singletonList(project1.uuid())).setMetricId(NCLOC_METRIC_ID), "P1_M1");
- verifyMeasures(MeasureQuery.builder().setProjectUuids(asList(project1.uuid(), project2.uuid())).setMetricIds(asList(NCLOC_METRIC_ID, COVERAGE_METRIC_ID)),
- "P1_M1", "P1_M2", "P2_M1", "P2_M2", "P2_M2");
- verifyMeasures(MeasureQuery.builder().setProjectUuids(asList(project1.uuid(), project2.uuid(), "UNKNOWN")).setMetricId(NCLOC_METRIC_ID), "P1_M1", "P2_M1");
+ verifyMeasure(project1.uuid(), ncloc.getKey(), "P1_M1");
// projects measures of none last analysis
- verifyMeasures(MeasureQuery.builder().setProjectUuids(singletonList(project1.uuid())).setMetricId(NCLOC_METRIC_ID).setAnalysisUuid(pastAnalysis.getUuid()), "P1_M3");
- verifyMeasures(MeasureQuery.builder().setProjectUuids(asList(project1.uuid(), project2.uuid())).setMetricId(NCLOC_METRIC_ID).setAnalysisUuid(pastAnalysis.getUuid()), "P1_M3");
+ verifyMeasure(project1.uuid(), ncloc.getKey(), pastAnalysis.getUuid(), "P1_M3");
}
@Test
@@ -193,35 +176,44 @@ public class MeasureDaoTest {
db.commit();
// project
- insertMeasure("PROJECT_M1", lastAnalysis.getUuid(), project.uuid(), NCLOC_METRIC_ID);
- insertMeasure("PROJECT_M2", pastAnalysis.getUuid(), project.uuid(), NCLOC_METRIC_ID);
- insertMeasure("PROJECT_M3", "OLD_ANALYSIS_UUID", project.uuid(), NCLOC_METRIC_ID);
+ insertMeasure("PROJECT_M1", lastAnalysis.getUuid(), project.uuid(), ncloc.getId());
+ insertMeasure("PROJECT_M2", pastAnalysis.getUuid(), project.uuid(), ncloc.getId());
+ insertMeasure("PROJECT_M3", "OLD_ANALYSIS_UUID", project.uuid(), ncloc.getId());
db.commit();
// Measures of project for last and previous analyses
List<MeasureDto> result = underTest.selectPastMeasures(db.getSession(),
- new PastMeasureQuery(project.uuid(), singletonList(NCLOC_METRIC_ID), previousAnalysisDate, lastAnalysisDate + 1_000L));
+ new PastMeasureQuery(project.uuid(), singletonList(ncloc.getId()), previousAnalysisDate, lastAnalysisDate + 1_000L));
assertThat(result).hasSize(2).extracting(MeasureDto::getData).containsOnly("PROJECT_M1", "PROJECT_M2");
}
- private void verifyMeasures(MeasureQuery.Builder query, String... expectedIds) {
- List<MeasureDto> measures = underTest.selectByQuery(db.getSession(), query.build());
- assertThat(measures).extracting(MeasureDto::getData).containsOnly(expectedIds);
+ private void verifyMeasure(String componentUuid, String metricKey, String analysisUuid, String value) {
+ Optional<MeasureDto> measure = underTest.selectMeasure(db.getSession(), analysisUuid, componentUuid, metricKey);
+ assertThat(measure.map(MeasureDto::getData)).contains(value);
+ }
+
+ private void verifyMeasure(String componentUuid, String metricKey, String value) {
+ Optional<MeasureDto> measure = underTest.selectLastMeasure(db.getSession(), componentUuid, metricKey);
+ assertThat(measure.map(MeasureDto::getData)).contains(value);
+ }
+
+ private void verifyNoMeasure(String componentUuid, String metricKey, String analysisUuid) {
+ assertThat(underTest.selectMeasure(db.getSession(), analysisUuid, componentUuid, metricKey)).isEmpty();
}
- private void verifyZeroMeasures(MeasureQuery.Builder query) {
- assertThat(underTest.selectByQuery(db.getSession(), query.build())).isEmpty();
+ private void verifyNoMeasure(String componentUuid, String metricKey) {
+ assertThat(underTest.selectLastMeasure(db.getSession(), componentUuid, metricKey)).isEmpty();
}
- private void insertMeasure(String id, String analysisUuid, String componentUuid, int metricId) {
+ private void insertMeasure(String value, String analysisUuid, String componentUuid, int metricId) {
MeasureDto measure = MeasureTesting.newMeasure()
.setAnalysisUuid(analysisUuid)
.setComponentUuid(componentUuid)
.setMetricId(metricId)
// as ids can't be forced when inserting measures, the field "data"
- // is used to store a virtual id. It is used then in assertions.
- .setData(id);
+ // is used to store a virtual value. It is used then in assertions.
+ .setData(value);
db.getDbClient().measureDao().insert(db.getSession(), measure);
}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureQueryTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureQueryTest.java
deleted file mode 100644
index 1839dde5eb0..00000000000
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/MeasureQueryTest.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2020 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.Rule;
-import org.junit.Test;
-import org.junit.rules.ExpectedException;
-
-import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class MeasureQueryTest {
-
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
-
- @Test
- public void create_query_from_projects() {
- MeasureQuery query = MeasureQuery.builder().setProjectUuids(asList("PROJECT_1", "PROJECT_2")).build();
-
- assertThat(query.getProjectUuids()).containsOnly("PROJECT_1", "PROJECT_2");
- assertThat(query.isOnProjects()).isTrue();
- assertThat(query.isOnComponents()).isFalse();
- assertThat(query.isOnSingleComponent()).isFalse();
- }
-
- @Test
- public void create_query_from_project_and_components() {
- MeasureQuery query = MeasureQuery.builder().setComponentUuids("PROJECT_1", asList("FILE_1", "FILE_2")).build();
-
- assertThat(query.getProjectUuids()).containsOnly("PROJECT_1");
- assertThat(query.getProjectUuid()).isEqualTo("PROJECT_1");
- assertThat(query.getComponentUuids()).containsOnly("FILE_1", "FILE_2");
- assertThat(query.isOnProjects()).isFalse();
- assertThat(query.isOnComponents()).isTrue();
- assertThat(query.isOnSingleComponent()).isFalse();
- }
-
- @Test
- public void create_query_from_single_component_uuid() {
- MeasureQuery query = MeasureQuery.builder().setComponentUuid("FILE_1").build();
-
- assertThat(query.getComponentUuids()).containsOnly("FILE_1");
- assertThat(query.getComponentUuid()).isEqualTo("FILE_1");
- assertThat(query.isOnProjects()).isFalse();
- assertThat(query.isOnComponents()).isFalse();
- assertThat(query.isOnSingleComponent()).isTrue();
- }
-
- @Test
- public void create_query_from_metric_ids() {
- MeasureQuery query = MeasureQuery.builder().setProjectUuids(asList("PROJECT_1", "PROJECT_2")).setMetricIds(asList(10, 11)).build();
-
- assertThat(query.getMetricIds()).containsOnly(10, 11);
- assertThat(query.getMetricKeys()).isNull();
- }
-
- @Test
- public void create_query_from_metric_keys() {
- MeasureQuery query = MeasureQuery.builder().setProjectUuids(asList("PROJECT_1", "PROJECT_2")).setMetricKeys(asList("M1", "M2")).build();
-
- assertThat(query.getMetricKeys()).containsOnly("M1", "M2");
- assertThat(query.getMetricIds()).isNull();
- }
-
- @Test
- public void return_empty_when_metrics_are_empty() {
- assertThat(MeasureQuery.builder()
- .setProjectUuids(asList("PROJECT_1", "PROJECT_2"))
- .setMetricKeys(emptyList())
- .build().returnsEmpty()).isTrue();
-
- assertThat(MeasureQuery.builder()
- .setProjectUuids(asList("PROJECT_1", "PROJECT_2"))
- .setMetricIds(emptyList())
- .build().returnsEmpty()).isTrue();
- }
-
- @Test
- public void return_empty_when_projects_are_empty() {
- assertThat(MeasureQuery.builder()
- .setProjectUuids(emptyList())
- .build().returnsEmpty()).isTrue();
- }
-
- @Test
- public void return_empty_when_components_are_empty() {
- assertThat(MeasureQuery.builder()
- .setComponentUuids("PROJECT", emptyList())
- .build().returnsEmpty()).isTrue();
- }
-
- @Test
- public void fail_when_no_component_uuid_filter() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("At least one filter on component UUID is expected");
- MeasureQuery.builder().build();
- }
-
- @Test
- public void fail_when_component_uuids_without_project_uuid() {
- expectedException.expect(NullPointerException.class);
- MeasureQuery.builder().setComponentUuids(null, asList("FILE_1", "FILE_2")).build();
- }
-
- @Test
- public void fail_when_using_metric_ids_and_metric_keys() {
- expectedException.expect(IllegalArgumentException.class);
- expectedException.expectMessage("Metric IDs and keys must not be set both");
- MeasureQuery.builder().setMetricIds(asList(10, 11)).setMetricKeys(asList("M1", "M2")).setProjectUuids(asList("PROJECT_1", "PROJECT_2")).build();
- }
-
-}