]> source.dussan.org Git - sonarqube.git/commitdiff
add MeasureDao.selectProjectMeasuresByDeveloperForMetrics
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 19 Jan 2016 15:39:39 +0000 (16:39 +0100)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 20 Jan 2016 13:46:14 +0000 (14:46 +0100)
sonar-db/src/main/java/org/sonar/db/measure/MeasureDao.java
sonar-db/src/main/java/org/sonar/db/measure/MeasureMapper.java
sonar-db/src/main/resources/org/sonar/db/measure/MeasureMapper.xml
sonar-db/src/test/java/org/sonar/db/measure/MeasureDaoTest.java

index eb82353aaa2225d6ebe860e16085a5f7f8262263..61c95ebb10c752b11965a8e2038b138cb06074c1 100644 (file)
@@ -105,6 +105,9 @@ public class MeasureDao implements Dao {
     });
   }
 
+  /**
+   * Used by plugin Developer Cockpit
+   */
   public List<MeasureDto> selectBySnapshotIdsAndMetricIds(final DbSession dbSession, List<Long> snapshotIds, final List<Integer> metricIds) {
     return DatabaseUtils.executeLargeInputs(snapshotIds, new Function<List<Long>, List<MeasureDto>>() {
       @Override
@@ -115,6 +118,16 @@ public class MeasureDao implements Dao {
     });
   }
 
+  /**
+   * Retrieves all measures associated to a specific developer and to the last snapshot of any project.
+   * <strong>property {@link MeasureDto#componentId} of the returned objects is populated</strong>
+   *
+   * Used by Developer Cockpit
+   */
+  public List<MeasureDto> selectProjectMeasuresByDeveloperForMetrics(DbSession dbSession, long developerId, Collection<Integer> metricIds) {
+    return mapper(dbSession).selectProjectMeasuresByDeveloperForMetrics(developerId, metricIds);
+  }
+
   public void insert(DbSession session, MeasureDto measureDto) {
     mapper(session).insert(measureDto);
   }
index 996d765c5fd5f8b7b9af2917b0c5bb3570cafacb..82bf90bd0f19126c2f2485f3d3cecbba135db853 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.db.measure;
 
+import java.util.Collection;
 import java.util.List;
 import javax.annotation.CheckForNull;
 import org.apache.ibatis.annotations.Param;
@@ -38,6 +39,8 @@ public interface MeasureMapper {
 
   List<MeasureDto> selectBySnapshotIdsAndMetricIds(@Param("snapshotIds") List<Long> snapshotIds, @Param("metricIds") List<Integer> metricIds);
 
+  List<MeasureDto> selectProjectMeasuresByDeveloperForMetrics(@Param("developerId") long developerId, @Param("metricIds") Collection<Integer> metricIds);
+
   @CheckForNull
   MeasureDto selectByComponentAndMetric(@Param("componentKey") String componentKey, @Param("metricKey") String metricKey);
 
index ed8a80b3f70db33c809d7a2cc6fb12948661a0ac..93a1fa7c7d8312ba4c5240267815529daca9aa93 100644 (file)
     </where>
   </select>
 
+  <select id="selectProjectMeasuresByDeveloperForMetrics" parameterType="map" resultType="Measure">
+    SELECT
+    <include refid="measureColumns"/>,
+    s.project_id as componentId
+    FROM project_measures pm
+    INNER JOIN snapshots s ON s.id=pm.snapshot_id AND s.islast=${_true} AND s.scope='PRJ' AND s.qualifier='TRK'
+    <where>
+      pm.person_id = #{developerId}
+      AND
+      pm.metric_id in
+      <foreach item="metricId" collection="metricIds" open="(" separator="," close=")">
+        #{metricId}
+      </foreach>
+      AND pm.rule_id is NULL
+      AND pm.characteristic_id is NULL
+    </where>
+  </select>
+
   <select id="selectBySnapshotAndMetrics" parameterType="map" resultType="Measure">
     SELECT
     <include refid="measureColumns"/>
index f9f943d4422fcf72e9d6ddd31a3786c9418223c5..83e5f34f46aaf46b0b960fd745bea40ca5eafcee 100644 (file)
@@ -33,7 +33,12 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.component.SnapshotDto;
 import org.sonar.test.DbTests;
 
 import static com.google.common.collect.Lists.newArrayList;
@@ -53,13 +58,16 @@ public class MeasureDaoTest {
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
 
-  MeasureDao underTest = db.getDbClient().measureDao();
+  private DbClient dbClient = db.getDbClient();
+  private DbSession dbSession = db.getSession();
+
+  MeasureDao underTest = dbClient.measureDao();
 
   @Test
   public void get_value_by_key() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc");
+    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc");
     assertThat(result.getId()).isEqualTo(22);
     assertThat(result.getValue()).isEqualTo(10d);
     assertThat(result.getData()).isNull();
@@ -77,7 +85,7 @@ public class MeasureDaoTest {
   public void get_data_by_key() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "authors_by_line");
+    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "authors_by_line");
     assertThat(result.getId()).isEqualTo(20);
     assertThat(result.getData()).isEqualTo("0123456789012345678901234567890123456789");
   }
@@ -86,7 +94,7 @@ public class MeasureDaoTest {
   public void get_text_value_by_key() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "coverage_line_hits_data");
+    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "coverage_line_hits_data");
     assertThat(result.getId()).isEqualTo(21);
     assertThat(result.getData()).isEqualTo("36=1;37=1;38=1;39=1;43=1;48=1;53=1");
   }
@@ -95,11 +103,11 @@ public class MeasureDaoTest {
   public void select_by_component_key_and_metrics() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    List<MeasureDto> results = underTest.selectByComponentKeyAndMetricKeys(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java",
+    List<MeasureDto> results = underTest.selectByComponentKeyAndMetricKeys(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java",
       newArrayList("ncloc", "authors_by_line"));
     assertThat(results).hasSize(2);
 
-    results = underTest.selectByComponentKeyAndMetricKeys(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", newArrayList("ncloc"));
+    results = underTest.selectByComponentKeyAndMetricKeys(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", newArrayList("ncloc"));
     assertThat(results).hasSize(1);
 
     MeasureDto result = results.get(0);
@@ -117,7 +125,7 @@ public class MeasureDaoTest {
   public void select_by_snapshotId_and_metrics() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, ImmutableSet.of("ncloc", "authors_by_line"), db.getSession());
+    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, ImmutableSet.of("ncloc", "authors_by_line"), dbSession);
     assertThat(results).hasSize(2);
 
     Optional<MeasureDto> optional = FluentIterable.from(results).filter(new Predicate<MeasureDto>() {
@@ -144,7 +152,7 @@ public class MeasureDaoTest {
   public void find_by_component_key_and_metric() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc");
+    MeasureDto result = underTest.selectByComponentKeyAndMetricKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc");
     assertThat(result.getId()).isEqualTo(22);
     assertThat(result.getValue()).isEqualTo(10d);
     assertThat(result.getMetricKey()).isEqualTo("ncloc");
@@ -154,22 +162,22 @@ public class MeasureDaoTest {
     assertThat(result.getVariation(4)).isEqualTo(4d);
     assertThat(result.getVariation(5)).isEqualTo(-5d);
 
-    assertThat(underTest.selectByComponentKeyAndMetricKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "unknown")).isNull();
+    assertThat(underTest.selectByComponentKeyAndMetricKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "unknown")).isNull();
   }
 
   @Test
   public void exists_by_key() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    assertThat(underTest.existsByKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc")).isTrue();
-    assertThat(underTest.existsByKey(db.getSession(), "org.struts:struts-core:src/org/struts/RequestContext.java", "unknown")).isFalse();
+    assertThat(underTest.existsByKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc")).isTrue();
+    assertThat(underTest.existsByKey(dbSession, "org.struts:struts-core:src/org/struts/RequestContext.java", "unknown")).isFalse();
   }
 
   @Test
   public void select_past_measures_by_component_uuid_and_root_snapshot_id_and_metric_keys() {
     db.prepareDbUnit(getClass(), "past_measures.xml");
 
-    List<PastMeasureDto> fileMeasures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "CDEF", 1000L, ImmutableSet.of(1, 2));
+    List<PastMeasureDto> fileMeasures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "CDEF", 1000L, ImmutableSet.of(1, 2));
     assertThat(fileMeasures).hasSize(2);
 
     PastMeasureDto fileMeasure1 = fileMeasures.get(0);
@@ -183,7 +191,7 @@ public class MeasureDaoTest {
     assertThat(fileMeasure2.getValue()).isEqualTo(60d);
     assertThat(fileMeasure2.getMetricId()).isEqualTo(2);
 
-    List<PastMeasureDto> projectMeasures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "ABCD", 1000L, ImmutableSet.of(1, 2));
+    List<PastMeasureDto> projectMeasures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "ABCD", 1000L, ImmutableSet.of(1, 2));
     assertThat(projectMeasures).hasSize(2);
 
     PastMeasureDto projectMeasure1 = projectMeasures.get(0);
@@ -194,17 +202,17 @@ public class MeasureDaoTest {
     assertThat(projectMeasure2.getValue()).isEqualTo(80d);
     assertThat(projectMeasure2.getMetricId()).isEqualTo(2);
 
-    assertThat(underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "UNKNOWN", 1000L, ImmutableSet.of(1, 2))).isEmpty();
-    assertThat(underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "CDEF", 987654L, ImmutableSet.of(1, 2))).isEmpty();
-    assertThat(underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "CDEF", 1000L, ImmutableSet.of(123, 456))).isEmpty();
+    assertThat(underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "UNKNOWN", 1000L, ImmutableSet.of(1, 2))).isEmpty();
+    assertThat(underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "CDEF", 987654L, ImmutableSet.of(1, 2))).isEmpty();
+    assertThat(underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "CDEF", 1000L, ImmutableSet.of(123, 456))).isEmpty();
   }
 
   @Test
   public void select_past_measures_on_rule_by_component_uuid_and_root_snapshot_id_and_metric_keys() {
     db.prepareDbUnit(getClass(), "past_measures_with_rule_id.xml");
-    db.getSession().commit();
+    dbSession.commit();
 
-    List<PastMeasureDto> measures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "ABCD", 1000L, ImmutableSet.of(1));
+    List<PastMeasureDto> measures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "ABCD", 1000L, ImmutableSet.of(1));
     assertThat(measures).hasSize(3);
 
     Map<Long, PastMeasureDto> pastMeasuresById = pastMeasuresById(measures);
@@ -235,7 +243,7 @@ public class MeasureDaoTest {
   public void select_past_measures_on_characteristic_by_component_uuid_and_root_snapshot_id_and_metric_keys() {
     db.prepareDbUnit(getClass(), "past_measures_with_characteristic_id.xml");
 
-    List<PastMeasureDto> measures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "ABCD", 1000L, ImmutableSet.of(1));
+    List<PastMeasureDto> measures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "ABCD", 1000L, ImmutableSet.of(1));
     assertThat(measures).hasSize(3);
 
     Map<Long, PastMeasureDto> pastMeasuresById = pastMeasuresById(measures);
@@ -266,7 +274,7 @@ public class MeasureDaoTest {
   public void select_past_measures_ignore_measures_with_person_id() {
     db.prepareDbUnit(getClass(), "past_measures_with_person_id.xml");
 
-    List<PastMeasureDto> measures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(db.getSession(), "ABCD", 1000L, ImmutableSet.of(1));
+    List<PastMeasureDto> measures = underTest.selectByComponentUuidAndProjectSnapshotIdAndMetricIds(dbSession, "ABCD", 1000L, ImmutableSet.of(1));
     assertThat(measures).hasSize(1);
 
     Map<Long, PastMeasureDto> pastMeasuresById = pastMeasuresById(measures);
@@ -279,10 +287,10 @@ public class MeasureDaoTest {
   public void select_by_snapshot_and_metric_keys() throws Exception {
     db.prepareDbUnit(getClass(), "select_by_snapshot_and_metric_keys.xml");
 
-    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc", "authors_by_line"), db.getSession());
+    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc", "authors_by_line"), dbSession);
     assertThat(results).hasSize(2);
 
-    results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc"), db.getSession());
+    results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc"), dbSession);
     assertThat(results).hasSize(1);
 
     MeasureDto result = results.get(0);
@@ -294,15 +302,15 @@ public class MeasureDaoTest {
     assertThat(result.getVariation(4)).isEqualTo(4d);
     assertThat(result.getVariation(5)).isEqualTo(-5d);
 
-    assertThat(underTest.selectBySnapshotIdAndMetricKeys(123, newHashSet("ncloc"), db.getSession())).isEmpty();
-    assertThat(underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, Collections.<String>emptySet(), db.getSession())).isEmpty();
+    assertThat(underTest.selectBySnapshotIdAndMetricKeys(123, newHashSet("ncloc"), dbSession)).isEmpty();
+    assertThat(underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, Collections.<String>emptySet(), dbSession)).isEmpty();
   }
 
   @Test
   public void select_by_snapshot_and_metric_keys_return_measures_with_rule_id() throws Exception {
     db.prepareDbUnit(getClass(), "select_by_snapshot_and_metric_keys_with_rule_id.xml");
 
-    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc"), db.getSession());
+    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc"), dbSession);
     assertThat(results).hasSize(3);
 
     Map<Long, MeasureDto> measuresById = measuresById(results);
@@ -315,7 +323,7 @@ public class MeasureDaoTest {
   public void select_by_snapshot_and_metric_keys_return_measures_with_characteristic_id() throws Exception {
     db.prepareDbUnit(getClass(), "select_by_snapshot_and_metric_keys_with_characteristic_id.xml");
 
-    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc"), db.getSession());
+    List<MeasureDto> results = underTest.selectBySnapshotIdAndMetricKeys(SNAPSHOT_ID, newHashSet("ncloc"), dbSession);
     assertThat(results).hasSize(3);
 
     Map<Long, MeasureDto> measuresById = measuresById(results);
@@ -328,7 +336,7 @@ public class MeasureDaoTest {
   public void selectByDeveloperForSnapshotAndMetrics_when_there_is_no_measure_for_developer_returns_empty() {
     db.prepareDbUnit(getClass(), "shared.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(dbSession,
       DEVELOPER_ID, SNAPSHOT_ID,
       ImmutableList.of(AUTHORS_BY_LINE_METRIC_ID, COVERAGE_LINE_HITS_DATA_METRIC_ID, NCLOC_METRIC_ID));
 
@@ -339,7 +347,7 @@ public class MeasureDaoTest {
   public void selectByDeveloperForSnapshotAndMetrics_returns_only_measures_for_developer() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(dbSession,
       DEVELOPER_ID, SNAPSHOT_ID,
       ImmutableList.of(AUTHORS_BY_LINE_METRIC_ID, COVERAGE_LINE_HITS_DATA_METRIC_ID, NCLOC_METRIC_ID));
 
@@ -350,7 +358,7 @@ public class MeasureDaoTest {
   public void selectByDeveloperForSnapshotAndMetrics_returns_only_measures_for_developer_and_specified_metric_id() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(dbSession,
       DEVELOPER_ID, SNAPSHOT_ID,
       ImmutableList.of(NCLOC_METRIC_ID));
 
@@ -361,7 +369,7 @@ public class MeasureDaoTest {
   public void selectBySnapshotAndMetrics_returns_empty_when_single_metric_id_does_not_exist() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectBySnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectBySnapshotAndMetrics(dbSession,
       SNAPSHOT_ID,
       ImmutableList.of(666));
 
@@ -372,7 +380,7 @@ public class MeasureDaoTest {
   public void selectBySnapshotAndMetrics_returns_only_measures_not_for_developer() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectBySnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectBySnapshotAndMetrics(dbSession,
       SNAPSHOT_ID,
       ImmutableList.of(AUTHORS_BY_LINE_METRIC_ID, COVERAGE_LINE_HITS_DATA_METRIC_ID, NCLOC_METRIC_ID));
 
@@ -383,7 +391,7 @@ public class MeasureDaoTest {
   public void selectBySnapshotAndMetrics_returns_only_measures_not_for_developer_and_with_specified_metric_id() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectBySnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectBySnapshotAndMetrics(dbSession,
       SNAPSHOT_ID,
       ImmutableList.of(NCLOC_METRIC_ID));
 
@@ -394,7 +402,7 @@ public class MeasureDaoTest {
   public void selectByDeveloperForSnapshotAndMetrics_returns_empty_when_single_metric_id_does_not_exist() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(dbSession,
       DEVELOPER_ID, SNAPSHOT_ID,
       ImmutableList.of(666));
 
@@ -405,7 +413,7 @@ public class MeasureDaoTest {
   public void selectByDeveloperForSnapshotAndMetrics_returns_empty_when_snapshotId_does_not_exist() {
     db.prepareDbUnit(getClass(), "with_some_measures_for_developer.xml");
 
-    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(db.getSession(),
+    List<MeasureDto> measureDtos = underTest.selectByDeveloperForSnapshotAndMetrics(dbSession,
       DEVELOPER_ID, 10,
       ImmutableList.of(AUTHORS_BY_LINE_METRIC_ID, COVERAGE_LINE_HITS_DATA_METRIC_ID, NCLOC_METRIC_ID));
 
@@ -414,11 +422,98 @@ public class MeasureDaoTest {
 
   //TODO add test for selectBySnapshotIdsAndMetricIds
 
+  @Test
+  public void selectProjectMeasuresByDeveloperForMetrics_returns_empty_on_empty_db() {
+    assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID, AUTHORS_BY_LINE_METRIC_ID))).isEmpty();
+  }
+
+  @Test
+  public void selectProjectMeasuresByDeveloperForMetrics_returns_empty_when_no_measure_for_developer() {
+    long otherDeveloperId = 666l;
+
+    ComponentDto projectDto = insertProject("aa");
+    SnapshotDto snapshotDto = insertSnapshot(projectDto, true);
+    insertMeasure(snapshotDto, DEVELOPER_ID, NCLOC_METRIC_ID, 12d);
+
+    List<MeasureDto> measureDtos = underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID));
+    assertThat(measureDtos).hasSize(1);
+    MeasureDto measureDto = measureDtos.iterator().next();
+    assertThat(measureDto.getId()).isNotNull();
+    assertThat(measureDto.getMetricId()).isEqualTo(NCLOC_METRIC_ID);
+    assertThat(measureDto.getSnapshotId()).isEqualTo(snapshotDto.getId());
+    assertThat(measureDto.getComponentId()).isEqualTo(projectDto.getId());
+    assertThat(measureDto.getDeveloperId()).isEqualTo(DEVELOPER_ID);
+
+    assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, otherDeveloperId, ImmutableList.of(NCLOC_METRIC_ID))).isEmpty();
+    assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(AUTHORS_BY_LINE_METRIC_ID))).isEmpty();
+  }
+
+  @Test
+  public void selectProjectMeasuresByDeveloperForMetrics_returns_ignores_measure_of_non_last_snapshot() {
+    long otherDeveloperId = 666l;
+
+    ComponentDto projectDto = insertProject("aa");
+    SnapshotDto nonLastSnapshotDto = insertSnapshot(projectDto, false);
+    insertMeasure(nonLastSnapshotDto, DEVELOPER_ID, NCLOC_METRIC_ID, 12d);
+    SnapshotDto lastSnapshotDto = insertSnapshot(projectDto, true);
+    insertMeasure(lastSnapshotDto, otherDeveloperId, NCLOC_METRIC_ID, 15d);
+
+    assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID))).hasSize(0);
+
+    List<MeasureDto> measureDtos = underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, otherDeveloperId, ImmutableList.of(NCLOC_METRIC_ID));
+    assertThat(measureDtos).hasSize(1);
+    MeasureDto measureDto = measureDtos.iterator().next();
+    assertThat(measureDto.getMetricId()).isEqualTo(NCLOC_METRIC_ID);
+    assertThat(measureDto.getSnapshotId()).isEqualTo(lastSnapshotDto.getId());
+    assertThat(measureDto.getComponentId()).isEqualTo(projectDto.getId());
+    assertThat(measureDto.getDeveloperId()).isEqualTo(otherDeveloperId);
+    assertThat(measureDto.getValue()).isEqualTo(15d);
+  }
+
+  @Test
+  public void selectProjectMeasuresByDeveloperForMetrics_returns_ignores_snapshots_of_any_component_but_project() {
+    ComponentDto projectDto = insertProject("aa");
+    insertSnapshot(projectDto, true);
+    ComponentDto moduleDto =  insertComponent(ComponentTesting.newModuleDto(projectDto));
+    insertMeasure(insertSnapshot(moduleDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 15d);
+    ComponentDto dirDto =  insertComponent(ComponentTesting.newDirectory(moduleDto, "toto"));
+    insertMeasure(insertSnapshot(dirDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 25d);
+    ComponentDto fileDto =  insertComponent(ComponentTesting.newFileDto(moduleDto, "tutu"));
+    insertMeasure(insertSnapshot(fileDto, true), DEVELOPER_ID, NCLOC_METRIC_ID, 35d);
+
+    assertThat(underTest.selectProjectMeasuresByDeveloperForMetrics(dbSession, DEVELOPER_ID, ImmutableList.of(NCLOC_METRIC_ID))).isEmpty();
+  }
+
+  private ComponentDto insertComponent(ComponentDto moduleDto) {
+    dbClient.componentDao().insert(dbSession, moduleDto);
+    dbSession.commit();
+    return moduleDto;
+  }
+
+  private ComponentDto insertProject(String uuid) {
+    ComponentDto projectDto = ComponentTesting.newProjectDto(uuid);
+    return insertComponent(projectDto);
+  }
+
+  private SnapshotDto insertSnapshot(ComponentDto componentDto, boolean last) {
+    SnapshotDto snapshotDto = new SnapshotDto().setComponentId(componentDto.getId()).setLast(last).setQualifier(componentDto.qualifier()).setScope(componentDto.scope());
+    dbClient.snapshotDao().insert(dbSession, snapshotDto);
+    dbSession.commit();
+    return snapshotDto;
+  }
+
+  private MeasureDto insertMeasure(SnapshotDto snapshotDto, Long developerId, int metricId, double value) {
+    MeasureDto measureDto = new MeasureDto().setMetricId(metricId).setValue(value).setSnapshotId(snapshotDto.getId()).setDeveloperId(developerId);
+    dbClient.measureDao().insert(dbSession, measureDto);
+    dbSession.commit();
+    return measureDto;
+  }
+
   @Test
   public void insert() {
     db.prepareDbUnit(getClass(), "empty.xml");
 
-    underTest.insert(db.getSession(), new MeasureDto()
+    underTest.insert(dbSession, new MeasureDto()
       .setSnapshotId(2L)
       .setMetricId(3)
       .setCharacteristicId(4)
@@ -436,7 +531,7 @@ public class MeasureDaoTest {
       .setAlertText("alert-text")
       .setDescription("measure-description")
     );
-    db.getSession().commit();
+    dbSession.commit();
 
     db.assertDbUnit(getClass(), "insert-result.xml", new String[]{"id"}, "project_measures");
   }
@@ -445,7 +540,7 @@ public class MeasureDaoTest {
   public void insert_measures() {
     db.prepareDbUnit(getClass(), "empty.xml");
 
-    underTest.insert(db.getSession(), new MeasureDto()
+    underTest.insert(dbSession, new MeasureDto()
         .setSnapshotId(2L)
         .setMetricId(3)
         .setComponentId(6L)
@@ -456,7 +551,7 @@ public class MeasureDaoTest {
         .setComponentId(6L)
         .setValue(4.0d)
     );
-    db.getSession().commit();
+    dbSession.commit();
 
     assertThat(db.countRowsOfTable("project_measures")).isEqualTo(2);
   }