aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-dao
diff options
context:
space:
mode:
authorDaniel Schwarz <daniel.schwarz@sonarsource.com>2017-05-24 12:46:26 +0200
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>2017-06-09 08:26:48 +0200
commit884e34739f55e058819001936945e89b41035ffa (patch)
treec57f8840b71ebdba5fa0bd783eb37e900870f205 /server/sonar-db-dao
parent2fb2871f4be5ea216ab71e67b80622c040fd1791 (diff)
downloadsonarqube-884e34739f55e058819001936945e89b41035ffa.tar.gz
sonarqube-884e34739f55e058819001936945e89b41035ffa.zip
SONAR-9230 only index project measures, that will actually be used
Diffstat (limited to 'server/sonar-db-dao')
-rw-r--r--server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java119
-rw-r--r--server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasuresIndexerIteratorTest.java8
2 files changed, 56 insertions, 71 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
index 11741d794fe..490899e82a3 100644
--- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
+++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java
@@ -19,49 +19,54 @@
*/
package org.sonar.db.measure;
-import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
+import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.resources.Qualifiers;
import org.sonar.api.resources.Scopes;
import org.sonar.core.util.CloseableIterator;
import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbSession;
+import static java.util.Arrays.asList;
import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
import static org.sonar.api.measures.CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY;
-import static org.sonar.api.measures.Metric.ValueType.BOOL;
-import static org.sonar.api.measures.Metric.ValueType.FLOAT;
-import static org.sonar.api.measures.Metric.ValueType.INT;
-import static org.sonar.api.measures.Metric.ValueType.LEVEL;
-import static org.sonar.api.measures.Metric.ValueType.MILLISEC;
-import static org.sonar.api.measures.Metric.ValueType.PERCENT;
-import static org.sonar.api.measures.Metric.ValueType.RATING;
-import static org.sonar.api.measures.Metric.ValueType.WORK_DUR;
import static org.sonar.api.utils.KeyValueFormat.parseStringInt;
-import static org.sonar.db.DatabaseUtils.repeatCondition;
import static org.sonar.db.component.DbTagsReader.readDbTags;
public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMeasuresIndexerIterator.ProjectMeasures> {
- private static final Set<String> METRIC_TYPES = ImmutableSet.of(INT.name(), FLOAT.name(), PERCENT.name(), BOOL.name(), MILLISEC.name(), LEVEL.name(), RATING.name(),
- WORK_DUR.name());
-
- private static final Joiner METRICS_JOINER = Joiner.on("','");
+ public static final Set<String> METRIC_KEYS = new HashSet<>(asList(
+ CoreMetrics.NCLOC_KEY,
+ CoreMetrics.DUPLICATED_LINES_DENSITY_KEY,
+ CoreMetrics.COVERAGE_KEY,
+ CoreMetrics.SQALE_RATING_KEY,
+ CoreMetrics.RELIABILITY_RATING_KEY,
+ CoreMetrics.SECURITY_RATING_KEY,
+ CoreMetrics.ALERT_STATUS_KEY,
+ CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION_KEY,
+ CoreMetrics.NEW_SECURITY_RATING_KEY,
+ CoreMetrics.NEW_MAINTAINABILITY_RATING_KEY,
+ CoreMetrics.NEW_COVERAGE_KEY,
+ CoreMetrics.NEW_DUPLICATED_LINES_DENSITY_KEY,
+ CoreMetrics.NEW_LINES_KEY,
+ CoreMetrics.NEW_RELIABILITY_RATING_KEY));
private static final String SQL_PROJECTS = "SELECT p.organization_uuid, p.uuid, p.kee, p.name, s.uuid, s.created_at, p.tags " +
"FROM projects p " +
@@ -70,57 +75,37 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
private static final String PROJECT_FILTER = " AND p.uuid=?";
- private static final String SQL_METRICS = "SELECT m.id, m.name FROM metrics m " +
- "WHERE (m.val_type IN ('" + METRICS_JOINER.join(METRIC_TYPES) + "') OR m.name=?)" +
- "AND m.enabled=?";
-
- private static final String SQL_MEASURES = "SELECT pm.metric_id, pm.value, pm.variation_value_1, pm.text_value FROM project_measures pm " +
+ private static final String SQL_MEASURES = "SELECT m.name, pm.value, pm.variation_value_1, pm.text_value FROM project_measures pm " +
+ "INNER JOIN metrics m ON m.id = pm.metric_id " +
"WHERE pm.component_uuid = ? AND pm.analysis_uuid = ? " +
- "AND pm.metric_id IN ({metricIds}) " +
+ "AND m.name IN ({metricNames}) " +
"AND (pm.value IS NOT NULL OR pm.variation_value_1 IS NOT NULL OR pm.text_value IS NOT NULL) " +
- "AND pm.person_id IS NULL ";
+ "AND pm.person_id IS NULL " +
+ "AND m.enabled = ? ";
+ private static final boolean ENABLED = true;
+ private static final int FIELD_METRIC_NAME = 1;
+ private static final int FIELD_MEASURE_VALUE = 2;
+ private static final int FIELD_MEASURE_VARIATION_VALUE_1 = 3;
+ private static final int FIELD_MEASURE_TEXT_VALUE = 4;
private final PreparedStatement measuresStatement;
- private final Map<Long, String> metricKeysByIds;
private final Iterator<Project> projects;
- private ProjectMeasuresIndexerIterator(PreparedStatement measuresStatement, Map<Long, String> metricKeysByIds, List<Project> projects) {
+ private ProjectMeasuresIndexerIterator(PreparedStatement measuresStatement, List<Project> projects) {
this.measuresStatement = measuresStatement;
- this.metricKeysByIds = metricKeysByIds;
this.projects = projects.iterator();
}
public static ProjectMeasuresIndexerIterator create(DbSession session, @Nullable String projectUuid) {
try {
- Map<Long, String> metrics = selectMetricKeysByIds(session);
List<Project> projects = selectProjects(session, projectUuid);
- PreparedStatement projectsStatement = createMeasuresStatement(session, metrics.keySet());
- return new ProjectMeasuresIndexerIterator(projectsStatement, metrics, projects);
+ PreparedStatement projectsStatement = createMeasuresStatement(session);
+ return new ProjectMeasuresIndexerIterator(projectsStatement, projects);
} catch (SQLException e) {
throw new IllegalStateException("Fail to execute request to select all project measures", e);
}
}
- private static Map<Long, String> selectMetricKeysByIds(DbSession session) {
- Map<Long, String> metrics = new HashMap<>();
- try (PreparedStatement stmt = createMetricsStatement(session);
- ResultSet rs = stmt.executeQuery()) {
- while (rs.next()) {
- metrics.put(rs.getLong(1), rs.getString(2));
- }
- return metrics;
- } catch (SQLException e) {
- throw new IllegalStateException("Fail to execute request to select all metrics", e);
- }
- }
-
- private static PreparedStatement createMetricsStatement(DbSession session) throws SQLException {
- PreparedStatement stmt = session.getConnection().prepareStatement(SQL_METRICS);
- stmt.setString(1, NCLOC_LANGUAGE_DISTRIBUTION_KEY);
- stmt.setBoolean(2, true);
- return stmt;
- }
-
private static List<Project> selectProjects(DbSession session, @Nullable String projectUuid) {
List<Project> projects = new ArrayList<>();
try (PreparedStatement stmt = createProjectsStatement(session, projectUuid);
@@ -144,9 +129,11 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
private static PreparedStatement createProjectsStatement(DbSession session, @Nullable String projectUuid) {
try {
- String sql = SQL_PROJECTS;
- sql += projectUuid == null ? "" : PROJECT_FILTER;
- PreparedStatement stmt = session.getConnection().prepareStatement(sql);
+ StringBuilder sql = new StringBuilder(SQL_PROJECTS);
+ if (projectUuid != null) {
+ sql.append(PROJECT_FILTER);
+ }
+ PreparedStatement stmt = session.getConnection().prepareStatement(sql.toString());
stmt.setBoolean(1, true);
stmt.setBoolean(2, true);
stmt.setString(3, Scopes.PROJECT);
@@ -160,16 +147,11 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
}
}
- private static PreparedStatement createMeasuresStatement(DbSession session, Set<Long> metricIds) throws SQLException {
+ private static PreparedStatement createMeasuresStatement(DbSession session) throws SQLException {
try {
- String sql = StringUtils.replace(SQL_MEASURES, "{metricIds}", repeatCondition("?", metricIds.size(), ","));
- PreparedStatement stmt = session.getConnection().prepareStatement(sql);
- int index = 3;
- for (Long metricId : metricIds) {
- stmt.setLong(index, metricId);
- index++;
- }
- return stmt;
+ String metricNameQuestionMarks = METRIC_KEYS.stream().map(x -> "?").collect(Collectors.joining(","));
+ String sql = StringUtils.replace(SQL_MEASURES, "{metricNames}", metricNameQuestionMarks);
+ return session.getConnection().prepareStatement(sql);
} catch (SQLException e) {
throw new IllegalStateException("Fail to prepare SQL request to select measures", e);
}
@@ -188,13 +170,16 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
private Measures selectMeasures(String projectUuid, @Nullable String analysisUuid) {
Measures measures = new Measures();
- if (analysisUuid == null || metricKeysByIds.isEmpty()) {
+ if (analysisUuid == null) {
return measures;
}
ResultSet rs = null;
try {
- measuresStatement.setString(1, projectUuid);
- measuresStatement.setString(2, analysisUuid);
+ AtomicInteger index = new AtomicInteger(1);
+ measuresStatement.setString(index.getAndIncrement(), projectUuid);
+ measuresStatement.setString(index.getAndIncrement(), analysisUuid);
+ METRIC_KEYS.forEach(DatabaseUtils.setStrings(measuresStatement, index::getAndIncrement));
+ measuresStatement.setBoolean(index.getAndIncrement(), ENABLED);
rs = measuresStatement.executeQuery();
while (rs.next()) {
readMeasure(rs, measures);
@@ -207,9 +192,9 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
}
}
- private void readMeasure(ResultSet rs, Measures measures) throws SQLException {
- String metricKey = metricKeysByIds.get(rs.getLong(1));
- Optional<Double> value = metricKey.startsWith("new_") ? getDouble(rs, 3) : getDouble(rs, 2);
+ private static void readMeasure(ResultSet rs, Measures measures) throws SQLException {
+ String metricKey = rs.getString(FIELD_METRIC_NAME);
+ Optional<Double> value = metricKey.startsWith("new_") ? getDouble(rs, FIELD_MEASURE_VARIATION_VALUE_1) : getDouble(rs, FIELD_MEASURE_VALUE);
if (value.isPresent()) {
measures.addNumericMeasure(metricKey, value.get());
return;
@@ -225,7 +210,7 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea
}
private static void readTextValue(ResultSet rs, Consumer<String> action) throws SQLException {
- String textValue = rs.getString(4);
+ String textValue = rs.getString(FIELD_MEASURE_TEXT_VALUE);
if (!rs.wasNull()) {
action.accept(textValue);
}
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasuresIndexerIteratorTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasuresIndexerIteratorTest.java
index 07b6da72a05..38ce4aa72a8 100644
--- a/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasuresIndexerIteratorTest.java
+++ b/server/sonar-db-dao/src/test/java/org/sonar/db/measure/ProjectMeasuresIndexerIteratorTest.java
@@ -162,7 +162,7 @@ public class ProjectMeasuresIndexerIteratorTest {
@Test
public void ignore_measure_that_does_not_have_value() throws Exception {
- MetricDto metric1 = insertIntMetric("lines");
+ MetricDto metric1 = insertIntMetric("coverage");
MetricDto metric2 = insertIntMetric("ncloc");
MetricDto leakMetric = insertIntMetric("new_lines");
ComponentDto project = ComponentTesting.newPrivateProjectDto(dbTester.getDefaultOrganization());
@@ -173,12 +173,12 @@ public class ProjectMeasuresIndexerIteratorTest {
MeasureDto withoutValue = insertMeasure(project, analysis, metric2, null, null);
Map<String, Double> numericMeasures = createResultSetAndReturnDocsById().get(project.uuid()).getMeasures().getNumericMeasures();
- assertThat(numericMeasures).containsOnly(entry("lines", 10d), entry("new_lines", 20d));
+ assertThat(numericMeasures).containsOnly(entry("coverage", 10d), entry("new_lines", 20d));
}
@Test
public void ignore_numeric_measure_that_has_text_value_but_not_numeric_value() throws Exception {
- MetricDto metric1 = insertIntMetric("lines");
+ MetricDto metric1 = insertIntMetric("coverage");
MetricDto metric2 = insertIntMetric("ncloc");
ComponentDto project = ComponentTesting.newPrivateProjectDto(dbTester.getDefaultOrganization());
SnapshotDto analysis = dbTester.components().insertProjectAndSnapshot(project);
@@ -187,7 +187,7 @@ public class ProjectMeasuresIndexerIteratorTest {
MeasureDto withTextValue = insertMeasure(project, analysis, metric2, "foo");
Map<String, Double> numericMeasures = createResultSetAndReturnDocsById().get(project.uuid()).getMeasures().getNumericMeasures();
- assertThat(numericMeasures).containsOnly(entry("lines", 10d));
+ assertThat(numericMeasures).containsOnly(entry("coverage", 10d));
}
@Test