diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2020-03-23 19:21:34 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-03-30 20:03:43 +0000 |
commit | 88597f3717a873db1373e4d4b2bcca7f5fd74425 (patch) | |
tree | c546b1449a8997d55c1fe18442013d1f09f06ba8 /server | |
parent | 9ea4d1c0a65d82acd4c4d3628a82b6a673fcb0c9 (diff) | |
download | sonarqube-88597f3717a873db1373e4d4b2bcca7f5fd74425.tar.gz sonarqube-88597f3717a873db1373e4d4b2bcca7f5fd74425.zip |
SONAR-12691 Refactor measures DAO
Diffstat (limited to 'server')
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(); - } - -} |