From 98c745aaed5d98118f47a57ef43317fb4962c8a8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Fri, 13 May 2016 09:59:47 +0200 Subject: [PATCH] SONAR-6846 don't fail on duplicate row in snapshot_sources --- .../sonar/db/version/v50/FeedFileSources.java | 22 ++++++++---- .../db/version/v50/FeedFileSourcesTest.java | 36 +++++++++++++++---- .../v50/FeedFileSourcesTest/schema.sql | 6 ++++ 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java index 83424ff4d5d..bf45c9ee424 100644 --- a/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java +++ b/sonar-db/src/main/java/org/sonar/db/version/v50/FeedFileSources.java @@ -96,7 +96,10 @@ public class FeedFileSources extends BaseDataChange { // duplication_data "m13.text_value, " + - "m13.measure_data " + + "m13.measure_data, " + + + // to detect multiple rows in snapshot_sources for the same snapshot + "s.id " + "FROM snapshots s " + "JOIN snapshot_sources ss " + @@ -137,15 +140,17 @@ public class FeedFileSources extends BaseDataChange { "f.enabled = ? " + "AND f.scope = 'FIL' " + "AND p.scope = 'PRJ' AND p.qualifier = 'TRK' " + - "AND fs.file_uuid IS NULL"; + "AND fs.file_uuid IS NULL " + + "ORDER BY s.id, ss.id desc"; public FeedFileSources(Database db, System2 system) { super(db); this.system = system; } - + private static final class FileSourceBuilder implements MassUpdate.Handler { private final long now; + private long previousSnapshotId = -1; public FileSourceBuilder(System2 system) { now = system.now(); @@ -183,6 +188,12 @@ public class FeedFileSources extends BaseDataChange { byte[] longOverallCovCond = row.getNullableBytes(28); byte[] shortDuplicationData = row.getNullableBytes(29); byte[] longDuplicationData = row.getNullableBytes(30); + long snapshotId = row.getLong(31); + + if (snapshotId == previousSnapshotId) { + return false; + } + this.previousSnapshotId = snapshotId; String[] sourceData = new FileSourceDto(source, ofNullableBytes(shortRevisions, longRevisions), @@ -197,8 +208,7 @@ public class FeedFileSources extends BaseDataChange { ofNullableBytes(shortOverallHits, longOverallHits), ofNullableBytes(shortOverallCond, longOverallCond), ofNullableBytes(shortOverallCovCond, longOverallCovCond), - ofNullableBytes(shortDuplicationData, longDuplicationData) - ).getSourceData(); + ofNullableBytes(shortDuplicationData, longDuplicationData)).getSourceData(); update.setString(1, projectUuid) .setString(2, fileUuid) @@ -210,7 +220,7 @@ public class FeedFileSources extends BaseDataChange { return true; } - + private static String ofNullableBytes(@Nullable byte[] shortBytes, @Nullable byte[] longBytes) { byte[] result; if (shortBytes == null) { diff --git a/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java index 665d31b9023..371b45f8fa0 100644 --- a/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java +++ b/sonar-db/src/test/java/org/sonar/db/version/v50/FeedFileSourcesTest.java @@ -66,6 +66,28 @@ public class FeedFileSourcesTest { migration.execute(); } + @Test + public void migrate_ignores_duplicate_multiple_rows_in_snapshot_source_for_the_same_snapshot() throws Exception { + db.prepareDbUnit(getClass(), "before.xml"); + db.executeUpdateSql("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')"); + + db.executeUpdateSql("insert into snapshot_sources " + + "(snapshot_id, data, updated_at) " + + "values " + + "(6, 'class Bar {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')"); + + migration.execute(); + + List> results = getFileSources(); + assertThat(results).hasSize(2); + + // the lastest inserted row is the one taken into account + assertThat(results.get(1).get("data")).isEqualTo(",,,,,,,,,,,,,,,class Bar {\r\n,,,,,,,,,,,,,,, // Empty\r\n,,,,,,,,,,,,,,,}\r\n,,,,,,,,,,,,,,,\r\n"); + } + @Test public void migrate_sources_with_no_scm_no_coverage() throws Exception { db.prepareDbUnit(getClass(), "before.xml"); @@ -82,8 +104,7 @@ public class FeedFileSourcesTest { migration.execute(); - List> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + - "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + List> results = getFileSources(); assertThat(results).hasSize(2); assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject"); @@ -243,8 +264,7 @@ public class FeedFileSourcesTest { migration.execute(); - List> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + - "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + List> results = getFileSources(); assertThat(results).hasSize(2); assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject"); @@ -305,8 +325,7 @@ public class FeedFileSourcesTest { // db.assertDbUnit(getClass(), "after-with-invalid-duplication.xml", "file_sources"); - List> results = db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + - "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + List> results = getFileSources(); assertThat(results).hasSize(2); assertThat(results.get(0).get("projectUuid")).isEqualTo("uuid-MyProject"); @@ -326,6 +345,11 @@ public class FeedFileSourcesTest { assertThat(results.get(1).get("createdAt")).isEqualTo(NOW); } + private List> getFileSources() { + return db.select("select project_uuid as \"projectUuid\", file_uuid as \"fileUuid\", created_at as \"createdAt\", " + + "updated_at as \"updatedAt\", data as \"data\", data as \"data\", line_hashes as \"lineHashes\", data_hash as \"dataHash\" from file_sources"); + } + private String formatLongDate(long dateInMs) { return DateUtils.formatDateTime(DateUtils.longToDate(dateInMs)); } diff --git a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql index 481ea89ba0a..2b1406f5af9 100644 --- a/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql +++ b/sonar-db/src/test/resources/org/sonar/db/version/v50/FeedFileSourcesTest/schema.sql @@ -117,3 +117,9 @@ CREATE TABLE "FILE_SOURCES" ( "CREATED_AT" BIGINT NOT NULL, "UPDATED_AT" BIGINT NOT NULL ); + +CREATE INDEX "FILE_SOURCES_PROJECT_UUID" ON "FILE_SOURCES" ("PROJECT_UUID"); + +CREATE UNIQUE INDEX "FILE_SOURCES_FILE_UUID_UNIQ" ON "FILE_SOURCES" ("FILE_UUID"); + +CREATE INDEX "FILE_SOURCES_UPDATED_AT" ON "FILE_SOURCES" ("UPDATED_AT"); -- 2.39.5