From: Julien HENRY Date: Tue, 25 Nov 2014 10:39:03 +0000 (+0100) Subject: SONAR-5866 Add coverage data into file_sources table + migration X-Git-Tag: 5.0-RC1~227 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=36d3e10c63ac339321cd4e1b6ae3efebdd5c4d9c;p=sonarqube.git SONAR-5866 Add coverage data into file_sources table + migration --- diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedFileSources.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedFileSources.java index d7f698f1800..43fb7a00831 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedFileSources.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FeedFileSources.java @@ -27,9 +27,13 @@ import org.sonar.server.db.migrations.Select.Row; import org.sonar.server.db.migrations.Select.RowReader; import org.sonar.server.db.migrations.SqlStatement; +import javax.annotation.Nullable; + import java.sql.SQLException; import java.util.Date; +import static com.google.common.base.Charsets.UTF_8; + /** * Used in the Active Record Migration 714 * @@ -56,8 +60,21 @@ public class FeedFileSources extends BaseDataChange { byte[] longAuthors = row.getBytes(8); byte[] shortDates = row.getBytes(9); byte[] longDates = row.getBytes(10); - - String[] sourceData = new FileSourceDto(source, shortRevisions, longRevisions, shortAuthors, longAuthors, shortDates, longDates).getSourceData(); + byte[] shortHits = row.getBytes(11); + byte[] longHits = row.getBytes(12); + byte[] shortCond = row.getBytes(13); + byte[] longCond = row.getBytes(14); + byte[] shortCovCond = row.getBytes(15); + byte[] longCovCond = row.getBytes(16); + + String[] sourceData = new FileSourceDto(source, + ofNullableBytes(shortRevisions, longRevisions), + ofNullableBytes(shortAuthors, longAuthors), + ofNullableBytes(shortDates, longDates), + ofNullableBytes(shortHits, longHits), + ofNullableBytes(shortCond, longCond), + ofNullableBytes(shortCovCond, longCovCond) + ).getSourceData(); update.setString(1, projectUuid) .setString(2, fileUuid) @@ -71,6 +88,20 @@ public class FeedFileSources extends BaseDataChange { } } + private static String ofNullableBytes(@Nullable byte[] shortBytes, @Nullable byte[] longBytes) { + byte[] result; + if (shortBytes == null) { + if (longBytes == null) { + return ""; + } else { + result = longBytes; + } + } else { + result = shortBytes; + } + return new String(result, UTF_8); + } + private final System2 system; public FeedFileSources(Database db, System2 system) { @@ -90,6 +121,9 @@ public class FeedFileSources extends BaseDataChange { Long revisionMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'revisions_by_line'").get(simpleLongReader); Long authorMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'authors_by_line'").get(simpleLongReader); Long datesMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'last_commit_datetimes_by_line'").get(simpleLongReader); + Long coverageHitsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'coverage_line_hits_data'").get(simpleLongReader); + Long conditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'conditions_by_line'").get(simpleLongReader); + Long coveredConditionsByLineMetricId = context.prepareSelect("SELECT id FROM metrics WHERE name = 'covered_conditions_by_line'").get(simpleLongReader); MassUpdate massUpdate = context.prepareMassUpdate(); massUpdate.select("SELECT " + @@ -102,7 +136,13 @@ public class FeedFileSources extends BaseDataChange { "m2.text_value as short_authors_by_line, " + "m2.measure_data as long_authors_by_line, " + "m3.text_value as short_dates_by_line, " + - "m3.measure_data as short_dates_by_line " + + "m3.measure_data as long_dates_by_line, " + + "m4.text_value as short_hits_by_line, " + + "m4.measure_data as long_hits_by_line, " + + "m5.text_value as short_cond_by_line, " + + "m5.measure_data as long_cond_by_line, " + + "m6.text_value as short_cover_cond_by_line, " + + "m6.measure_data as long_cover_cond_by_line " + "FROM snapshots s " + "JOIN snapshot_sources ss " + "ON s.id = ss.snapshot_id AND s.islast = ? " + @@ -116,6 +156,12 @@ public class FeedFileSources extends BaseDataChange { "ON m2.snapshot_id = s.id AND m2.metric_id = ? " + "LEFT JOIN project_measures m3 " + "ON m3.snapshot_id = s.id AND m3.metric_id = ? " + + "LEFT JOIN project_measures m4 " + + "ON m4.snapshot_id = s.id AND m4.metric_id = ? " + + "LEFT JOIN project_measures m5 " + + "ON m5.snapshot_id = s.id AND m5.metric_id = ? " + + "LEFT JOIN project_measures m6 " + + "ON m6.snapshot_id = s.id AND m6.metric_id = ? " + "WHERE " + "f.enabled = ? " + "AND f.scope = 'FIL' " + @@ -124,7 +170,10 @@ public class FeedFileSources extends BaseDataChange { .setLong(2, revisionMetricId != null ? revisionMetricId : 0L) .setLong(3, authorMetricId != null ? authorMetricId : 0L) .setLong(4, datesMetricId != null ? datesMetricId : 0L) - .setBoolean(5, true); + .setLong(5, coverageHitsByLineMetricId != null ? coverageHitsByLineMetricId : 0L) + .setLong(6, conditionsByLineMetricId != null ? conditionsByLineMetricId : 0L) + .setLong(7, coveredConditionsByLineMetricId != null ? coveredConditionsByLineMetricId : 0L) + .setBoolean(8, true); massUpdate.update("INSERT INTO file_sources" + "(project_uuid, file_uuid, created_at, updated_at, data, line_hashes, data_hash)" + diff --git a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FileSourceDto.java b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FileSourceDto.java index 31a5ec2849f..8163e27aab0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FileSourceDto.java +++ b/server/sonar-server/src/main/java/org/sonar/server/db/migrations/v50/FileSourceDto.java @@ -25,8 +25,6 @@ import org.apache.commons.lang.StringUtils; import org.sonar.api.utils.KeyValueFormat; import org.sonar.api.utils.text.CsvWriter; -import javax.annotation.Nullable; - import java.io.ByteArrayOutputStream; import java.io.OutputStreamWriter; import java.util.Iterator; @@ -41,17 +39,20 @@ class FileSourceDto { private Iterator sourceSplitter; private Map revisions; - private Map authors; - private Map dates; + private Map hits; + private Map conditions; + private Map coveredConditions; - FileSourceDto(String source, @Nullable byte[] shortRevisions, @Nullable byte[] longRevisions, @Nullable byte[] shortAuthors, @Nullable byte[] longAuthors, - @Nullable byte[] shortDates, @Nullable byte[] longDates) { + FileSourceDto(String source, String revisions, String authors, String dates, String hits, String conditions, String coveredConditions) { sourceSplitter = Splitter.onPattern("\r?\n|\r").split(source).iterator(); - revisions = KeyValueFormat.parseIntString(ofNullableBytes(shortRevisions, longRevisions)); - authors = KeyValueFormat.parseIntString(ofNullableBytes(shortAuthors, longAuthors)); - dates = KeyValueFormat.parseIntString(ofNullableBytes(shortDates, longDates)); + this.revisions = KeyValueFormat.parseIntString(revisions); + this.authors = KeyValueFormat.parseIntString(authors); + this.dates = KeyValueFormat.parseIntString(dates); + this.hits = KeyValueFormat.parseIntString(hits); + this.conditions = KeyValueFormat.parseIntString(conditions); + this.coveredConditions = KeyValueFormat.parseIntString(coveredConditions); } String[] getSourceData() { @@ -65,7 +66,9 @@ class FileSourceDto { line++; sourceLine = sourceSplitter.next(); lineHashes.append(lineChecksum(sourceLine)).append("\n"); - csv.values(revisions.get(line), authors.get(line), dates.get(line), highlighting, sourceLine); + csv.values(revisions.get(line), authors.get(line), dates.get(line), + hits.get(line), conditions.get(line), coveredConditions.get(line), + highlighting, sourceLine); } csv.close(); return new String[] {new String(output.toByteArray(), UTF_8), lineHashes.toString()}; @@ -79,17 +82,4 @@ class FileSourceDto { return DigestUtils.md5Hex(reducedLine); } - private static String ofNullableBytes(@Nullable byte[] shortBytes, @Nullable byte[] longBytes) { - byte[] result; - if (shortBytes == null) { - if (longBytes == null) { - return ""; - } else { - result = longBytes; - } - } else { - result = shortBytes; - } - return new String(result, UTF_8); - } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/FeedFileSourcesTest.java b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/FeedFileSourcesTest.java index f9f0e6a591a..6db143b42af 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/FeedFileSourcesTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/db/migrations/v50/FeedFileSourcesTest.java @@ -28,7 +28,6 @@ import org.junit.Test; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; import org.sonar.core.persistence.TestDatabase; -import org.sonar.server.db.migrations.DatabaseMigration; import java.sql.Connection; import java.sql.PreparedStatement; @@ -42,7 +41,7 @@ public class FeedFileSourcesTest { @ClassRule public static TestDatabase db = new TestDatabase().schema(FeedFileSourcesTest.class, "schema.sql"); - DatabaseMigration migration; + FeedFileSources migration; System2 system; @@ -67,7 +66,7 @@ public class FeedFileSourcesTest { } @Test - public void migrate_sources_with_no_scm() throws Exception { + public void migrate_sources_with_no_scm_no_coverage() throws Exception { db.prepareDbUnit(getClass(), "before.xml"); db.executeUpdateSql("insert into snapshot_sources " + @@ -81,7 +80,16 @@ public class FeedFileSourcesTest { } @Test - public void migrate_sources_with_scm() throws Exception { + public void migrate_sources_with_scm_and_coverage_in_text_value() throws Exception { + migrate_sources_with_scm_and_coverage_in("text_value"); + } + + @Test + public void migrate_sources_with_scm_and_coverage_in_measure_data() throws Exception { + migrate_sources_with_scm_and_coverage_in("measure_data"); + } + + private void migrate_sources_with_scm_and_coverage_in(String columnName) throws Exception { db.prepareDbUnit(getClass(), "before.xml"); Connection connection = null; @@ -95,30 +103,50 @@ public class FeedFileSourcesTest { .executeUpdate(); PreparedStatement revisionStmt = connection.prepareStatement("insert into project_measures " + - "(metric_id, snapshot_id, text_value) " + + "(metric_id, snapshot_id, " + columnName + ") " + "values " + "(1, 6, ?)"); revisionStmt.setBytes(1, "1=aef12a;2=abe465;3=afb789;4=afb789".getBytes(Charsets.UTF_8)); revisionStmt.executeUpdate(); PreparedStatement authorStmt = connection.prepareStatement("insert into project_measures " + - "(metric_id, snapshot_id, text_value) " + + "(metric_id, snapshot_id, " + columnName + ") " + "values " + "(2, 6, ?)"); authorStmt.setBytes(1, "1=alice;2=bob;3=carol;4=carol".getBytes(Charsets.UTF_8)); authorStmt.executeUpdate(); PreparedStatement dateStmt = connection.prepareStatement("insert into project_measures " + - "(metric_id, snapshot_id, text_value) " + + "(metric_id, snapshot_id, " + columnName + ") " + "values " + "(3, 6, ?)"); dateStmt.setBytes(1, "1=2014-04-25T12:34:56+0100;2=2014-07-25T12:34:56+0100;3=2014-03-23T12:34:56+0100;4=2014-03-23T12:34:56+0100".getBytes(Charsets.UTF_8)); dateStmt.executeUpdate(); + + PreparedStatement hitsStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(4, 6, ?)"); + hitsStmt.setBytes(1, "1=1;3=0".getBytes(Charsets.UTF_8)); + hitsStmt.executeUpdate(); + + PreparedStatement condStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(5, 6, ?)"); + condStmt.setBytes(1, "1=4".getBytes(Charsets.UTF_8)); + condStmt.executeUpdate(); + + PreparedStatement coveredCondStmt = connection.prepareStatement("insert into project_measures " + + "(metric_id, snapshot_id, " + columnName + ") " + + "values " + + "(6, 6, ?)"); + coveredCondStmt.setBytes(1, "1=2".getBytes(Charsets.UTF_8)); + coveredCondStmt.executeUpdate(); } finally { DbUtils.commitAndCloseQuietly(connection); } - migration.execute(); db.assertDbUnit(getClass(), "after-with-scm.xml", "file_sources"); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after-with-scm.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after-with-scm.xml index 0d6a7af4448..2b50c6c7b45 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after-with-scm.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after-with-scm.xml @@ -1,7 +1,7 @@ diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after.xml index 7a75bbc9589..baab80f397c 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/after.xml @@ -1,7 +1,7 @@ diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before-with-scm.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before-with-scm.xml deleted file mode 100644 index a32c8de21e0..00000000000 --- a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before-with-scm.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - diff --git a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before.xml b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before.xml index 4a84a085857..b6b6943e70f 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before.xml +++ b/server/sonar-server/src/test/resources/org/sonar/server/db/migrations/v50/FeedFileSourcesTest/before.xml @@ -6,6 +6,12 @@ user_managed="false" enabled="true" origin="JAV" worst_value="[null]" best_value="[null]" optimized_best_value="[null]" hidden="[false]" delete_historical_data="false" />