]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13221 Set primary key of 'SNAPSHOTS' table to column 'UUID' and drop 'ID'
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 3 Apr 2020 08:40:39 +0000 (10:40 +0200)
committersonartech <sonartech@sonarsource.com>
Mon, 25 May 2020 20:05:18 +0000 (20:05 +0000)
27 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/analysis/Analysis.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisImplTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/analysis/AnalysisMetadataHolderImplTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/filemove/FileMoveDetectionStepTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/scm/ScmInfoDbLoaderTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadCrossProjectDuplicationsRepositoryStepTest.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDto.java
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeableAnalysisDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml
server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml
server/sonar-db-dao/src/schema/schema-sq.ddl
server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/component/SnapshotDtoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/purge/period/DefaultPeriodCleanerTest.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/DbVersion83.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/AddPrimaryKeyOnUuidColumnOfSnapshotsTable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/DropIdColumnOfSnapshotsTable.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/DropPrimaryKeyOnIdColumnOfSnapshotsTable.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/DropIdColumnOfSnapshotsTableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/DropPrimaryKeyOnIdColumnOfSnapshotsTableTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest/schema.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/DropIdColumnOfSnapshotsTableTest/schema.sql [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/DropPrimaryKeyOnIdColumnOfSnapshotsTableTest/schema.sql [new file with mode: 0644]

index 24b8e35c44308550035200729fca15892c56340f..ac973cfec1a31c9ab1e8937c2d39b7a09768a2dd 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.ce.task.projectanalysis.analysis;
 
+import java.util.Objects;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 import javax.annotation.concurrent.Immutable;
@@ -28,20 +29,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
 @Immutable
 public class Analysis {
 
-  private long id;
   private String uuid;
   private long createdAt;
 
   private Analysis(Builder builder) {
-    this.id = builder.id;
     this.uuid = builder.uuid;
     this.createdAt = builder.createdAt;
   }
 
-  public long getId() {
-    return id;
-  }
-
   public String getUuid() {
     return uuid;
   }
@@ -51,18 +46,11 @@ public class Analysis {
   }
 
   public static final class Builder {
-    @CheckForNull
-    private Long id;
     @CheckForNull
     private String uuid;
     @CheckForNull
     private Long createdAt;
 
-    public Builder setId(long id) {
-      this.id = id;
-      return this;
-    }
-
     public Builder setUuid(String uuid) {
       this.uuid = uuid;
       return this;
@@ -74,7 +62,6 @@ public class Analysis {
     }
 
     public Analysis build() {
-      checkNotNull(id, "id cannot be null");
       checkNotNull(uuid, "uuid cannot be null");
       checkNotNull(createdAt, "createdAt cannot be null");
       return new Analysis(this);
@@ -91,19 +78,18 @@ public class Analysis {
     }
 
     Analysis analysis = (Analysis) o;
-    return id == analysis.id;
+    return Objects.equals(uuid, analysis.uuid);
   }
 
   @Override
   public int hashCode() {
-    return (int) (id ^ (id >>> 32));
+    return Objects.hash(uuid);
   }
 
   @Override
   public String toString() {
     return "Analysis{" +
-      "id=" + id +
-      ", uuid='" + uuid + '\'' +
+      "uuid='" + uuid + '\'' +
       ", createdAt=" + createdAt +
       '}';
   }
index d49e6df2d008a45c176ab6db1171136d3272b276..e26b7b8257909a6793b6bc42b62d8b217b014734 100644 (file)
@@ -143,7 +143,6 @@ public class BuildComponentTreeStep implements ComputationStep {
 
   private static Analysis toAnalysis(SnapshotDto dto) {
     return new Analysis.Builder()
-      .setId(dto.getId())
       .setUuid(dto.getUuid())
       .setCreatedAt(dto.getCreatedAt())
       .build();
index a1c1ca5f67faee87e474150a23e6869f6e27ad00..ae38500b5684298462a966a0e0a87b36984bbc9c 100644 (file)
@@ -37,34 +37,20 @@ public class AnalysisImplTest {
   @Test
   public void build_snapshot() {
     Analysis analysis = new Analysis.Builder()
-      .setId(ID)
       .setUuid(UUID)
       .setCreatedAt(CREATED_AT)
       .build();
 
-    assertThat(analysis.getId()).isEqualTo(ID);
     assertThat(analysis.getUuid()).isEqualTo(UUID);
     assertThat(analysis.getCreatedAt()).isEqualTo(CREATED_AT);
   }
 
-  @Test
-  public void fail_with_NPE_when_building_snapshot_without_id() {
-    thrown.expect(NullPointerException.class);
-    thrown.expectMessage("id cannot be null");
-
-    new Analysis.Builder()
-      .setUuid(UUID)
-      .setCreatedAt(CREATED_AT)
-      .build();
-  }
-
   @Test
   public void fail_with_NPE_when_building_snapshot_without_uuid() {
     thrown.expect(NullPointerException.class);
     thrown.expectMessage("uuid cannot be null");
 
     new Analysis.Builder()
-      .setId(ID)
       .setCreatedAt(CREATED_AT)
       .build();
   }
@@ -75,7 +61,6 @@ public class AnalysisImplTest {
     thrown.expectMessage("createdAt cannot be null");
 
     new Analysis.Builder()
-      .setId(ID)
       .setUuid(UUID)
       .build();
   }
@@ -83,45 +68,34 @@ public class AnalysisImplTest {
   @Test
   public void test_toString() {
     assertThat(new Analysis.Builder()
-      .setId(ID)
       .setUuid(UUID)
       .setCreatedAt(CREATED_AT)
       .build().toString())
-        .isEqualTo("Analysis{id=10, uuid='uuid ', createdAt=123456789}");
+        .isEqualTo("Analysis{uuid='uuid ', createdAt=123456789}");
   }
 
   @Test
   public void test_equals_and_hascode() {
     Analysis analysis = new Analysis.Builder()
-      .setId(ID)
       .setUuid(UUID)
       .setCreatedAt(CREATED_AT)
       .build();
     Analysis sameAnalysis = new Analysis.Builder()
-      .setId(ID)
       .setUuid(UUID)
       .setCreatedAt(CREATED_AT)
       .build();
-    Analysis sameAnalysisNotSameUuid = new Analysis.Builder()
-      .setId(ID)
-      .setUuid("other uuid")
-      .setCreatedAt(CREATED_AT)
-      .build();
     Analysis otherAnalysis = new Analysis.Builder()
-      .setId(11L)
-      .setUuid(UUID)
+      .setUuid("other uuid")
       .setCreatedAt(CREATED_AT)
       .build();
 
     assertThat(analysis).isEqualTo(analysis);
     assertThat(analysis).isEqualTo(sameAnalysis);
-    assertThat(analysis).isEqualTo(sameAnalysisNotSameUuid);
     assertThat(analysis).isNotEqualTo(otherAnalysis);
     assertThat(analysis).isNotEqualTo(null);
 
     assertThat(analysis.hashCode()).isEqualTo(analysis.hashCode());
     assertThat(analysis.hashCode()).isEqualTo(sameAnalysis.hashCode());
-    assertThat(analysis.hashCode()).isEqualTo(sameAnalysisNotSameUuid.hashCode());
     assertThat(analysis.hashCode()).isNotEqualTo(otherAnalysis.hashCode());
   }
 }
index 19c108021847eb152d57f1b748bf97de9c9bd5ab..b44c61bdc633b700a6f009bdc0c8cb9d8dc855ac 100644 (file)
@@ -47,7 +47,6 @@ import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
 public class AnalysisMetadataHolderImplTest {
 
   private static Analysis baseProjectAnalysis = new Analysis.Builder()
-    .setId(1)
     .setUuid("uuid_1")
     .setCreatedAt(123456789L)
     .build();
index 54173e19e6dbf373cea7e2356c5e35455675dab4..c50515ce4cec433e44be4b6d36428f1aa111400e 100644 (file)
@@ -62,10 +62,9 @@ import static org.sonar.ce.task.projectanalysis.filemove.FileMoveDetectionStep.M
 
 public class FileMoveDetectionStepTest {
 
-  private static final long SNAPSHOT_ID = 98765;
+  private static final String SNAPSHOT_UUID = "uuid_1";
   private static final Analysis ANALYSIS = new Analysis.Builder()
-    .setId(SNAPSHOT_ID)
-    .setUuid("uuid_1")
+    .setUuid(SNAPSHOT_UUID)
     .setCreatedAt(86521)
     .build();
   private static final int ROOT_REF = 1;
index 800bd0203aea9f668386882a21145251a9e4a62b..269878f2bc9d2a33ff4e514cbdd93fa0896226d4 100644 (file)
@@ -52,10 +52,8 @@ public class ScmInfoDbLoaderTest {
   static final int FILE_REF = 1;
   static final Component FILE = builder(Component.Type.FILE, FILE_REF).setKey("FILE_KEY").setUuid("FILE_UUID").build();
   static final long DATE_1 = 123456789L;
-  static final long DATE_2 = 1234567810L;
 
   static Analysis baseProjectAnalysis = new Analysis.Builder()
-    .setId(1)
     .setUuid("uuid_1")
     .setCreatedAt(123456789L)
     .build();
index 2d40c145935a1fbd33dc2d81d5ce9e87bb467fe6..22edc1049681d4b7e4524af305c1350d5e7b9bbd 100644 (file)
@@ -54,10 +54,12 @@ import org.sonar.duplications.block.ByteArray;
 import org.sonar.scanner.protocol.output.ScannerReport;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
@@ -111,7 +113,6 @@ public class LoadCrossProjectDuplicationsRepositoryStepTest {
     dbSession.commit();
 
     baseProjectAnalysis = new Analysis.Builder()
-      .setId(projectSnapshot.getId())
       .setUuid(projectSnapshot.getUuid())
       .setCreatedAt(projectSnapshot.getCreatedAt())
       .build();
@@ -145,12 +146,12 @@ public class LoadCrossProjectDuplicationsRepositoryStepTest {
       .setStartTokenIndex(0)
       .setEndTokenIndex(10)
       .build();
-    batchReportReader.putDuplicationBlocks(FILE_REF, asList(originBlock));
+    batchReportReader.putDuplicationBlocks(FILE_REF, singletonList(originBlock));
 
     underTest.execute(new TestComputationStepContext());
 
     verify(integrateCrossProjectDuplications).computeCpd(CURRENT_FILE,
-      asList(
+      singletonList(
         new Block.Builder()
           .setResourceId(CURRENT_FILE_KEY)
           .setBlockHash(new ByteArray(hash))
@@ -158,7 +159,7 @@ public class LoadCrossProjectDuplicationsRepositoryStepTest {
           .setLines(originBlock.getStartLine(), originBlock.getEndLine())
           .setUnit(originBlock.getStartTokenIndex(), originBlock.getEndTokenIndex())
           .build()),
-      asList(
+      singletonList(
         new Block.Builder()
           .setResourceId(otherFile.getDbKey())
           .setBlockHash(new ByteArray(hash))
@@ -283,7 +284,7 @@ public class LoadCrossProjectDuplicationsRepositoryStepTest {
       .setStartTokenIndex(0)
       .setEndTokenIndex(10)
       .build();
-    batchReportReader.putDuplicationBlocks(FILE_REF, asList(originBlock));
+    batchReportReader.putDuplicationBlocks(FILE_REF, singletonList(originBlock));
 
     underTest.execute(new TestComputationStepContext());
 
@@ -299,7 +300,7 @@ public class LoadCrossProjectDuplicationsRepositoryStepTest {
 
     underTest.execute(new TestComputationStepContext());
 
-    verifyZeroInteractions(integrateCrossProjectDuplications);
+    verifyNoInteractions(integrateCrossProjectDuplications);
   }
 
   @Test
@@ -314,11 +315,11 @@ public class LoadCrossProjectDuplicationsRepositoryStepTest {
       .setStartTokenIndex(0)
       .setEndTokenIndex(10)
       .build();
-    batchReportReader.putDuplicationBlocks(FILE_REF, asList(originBlock));
+    batchReportReader.putDuplicationBlocks(FILE_REF, singletonList(originBlock));
 
     underTest.execute(new TestComputationStepContext());
 
-    verifyZeroInteractions(integrateCrossProjectDuplications);
+    verifyNoInteractions(integrateCrossProjectDuplications);
   }
 
   private ComponentDto createProject(String projectKey) {
index ced97ee7fabbb27b00c2e9a18e95056d9b1a0a23..550b53ff0ce5859e1deae1534eafa45f971c76ca 100644 (file)
@@ -36,7 +36,6 @@ public final class SnapshotDto {
   public static final int MAX_VERSION_LENGTH = 100;
   public static final int MAX_BUILD_STRING_LENGTH = 100;
 
-  private Long id;
   private String uuid;
   private String componentUuid;
   private Long createdAt;
@@ -56,15 +55,6 @@ public final class SnapshotDto {
   @Nullable
   private String revision;
 
-  public Long getId() {
-    return id;
-  }
-
-  public SnapshotDto setId(Long id) {
-    this.id = id;
-    return this;
-  }
-
   public SnapshotDto setUuid(String s) {
     this.uuid = s;
     return this;
@@ -215,8 +205,7 @@ public final class SnapshotDto {
       return false;
     }
     SnapshotDto that = (SnapshotDto) o;
-    return Objects.equals(id, that.id) &&
-      Objects.equals(uuid, that.uuid) &&
+    return Objects.equals(uuid, that.uuid) &&
       Objects.equals(componentUuid, that.componentUuid) &&
       Objects.equals(createdAt, that.createdAt) &&
       Objects.equals(buildDate, that.buildDate) &&
@@ -231,14 +220,13 @@ public final class SnapshotDto {
 
   @Override
   public int hashCode() {
-    return Objects.hash(id, uuid, componentUuid, createdAt, buildDate, status, last, projectVersion, buildString, periodMode, periodParam, periodDate);
+    return Objects.hash(uuid, componentUuid, createdAt, buildDate, status, last, projectVersion, buildString, periodMode, periodParam, periodDate);
   }
 
   @Override
   public String toString() {
     return "SnapshotDto{" +
-      "id=" + id +
-      ", uuid='" + uuid + '\'' +
+      "uuid='" + uuid + '\'' +
       ", componentUuid='" + componentUuid + '\'' +
       ", createdAt=" + createdAt +
       ", buildDate=" + buildDate +
index 0e7f34871a4930b6729daea32e7467a7d1645823..b946ce4837758e34bc80f3e666aaa70abee6c6ba 100644 (file)
@@ -30,7 +30,6 @@ import org.apache.commons.lang.builder.ToStringStyle;
  */
 public class PurgeableAnalysisDto implements Comparable<PurgeableAnalysisDto> {
   private Date date;
-  private long analysisId;
   private String analysisUuid;
   private String version;
   private boolean hasEvents;
@@ -45,15 +44,6 @@ public class PurgeableAnalysisDto implements Comparable<PurgeableAnalysisDto> {
     return this;
   }
 
-  public long getAnalysisId() {
-    return analysisId;
-  }
-
-  public PurgeableAnalysisDto setAnalysisId(long analysisId) {
-    this.analysisId = analysisId;
-    return this;
-  }
-
   public String getAnalysisUuid() {
     return analysisUuid;
   }
index 082040e4bed82acdd4579dc115acf9b7453f7d27..aa53f2e4b82c2aa6c3afef7756bb5f91b1c8a12a 100644 (file)
@@ -3,7 +3,6 @@
 <mapper namespace="org.sonar.db.component.SnapshotMapper">
 
   <sql id="snapshotColumns">
-    s.id,
     s.uuid as uuid,
     s.component_uuid as componentUuId,
     s.created_at as createdAt,
     where uuid = #{uuid,jdbcType=VARCHAR}
   </update>
 
-  <insert id="insert" parameterType="Snapshot" keyColumn="id" useGeneratedKeys="true" keyProperty="id">
+  <insert id="insert" parameterType="Snapshot" useGeneratedKeys="false">
     insert into snapshots (
       uuid,
       component_uuid,
index d7869650ff45e2d9ba7fdd6bad411f858cd8853f..17453714d35d6f93b917cff6b1c412f1e39f7ae0 100644 (file)
@@ -24,7 +24,6 @@
 
   <select id="selectPurgeableAnalyses" parameterType="String" resultType="PurgeableAnalysis">
     select
-      s.id as "analysisId",
       s.uuid as "analysisUuid",
       s.created_at as "date",
       case when ve.analysis_uuid is not null then ${_true} else ${_false} end as "hasEvents",
index 74be76f621fbafbb901df9c5c5a8cf3fae3744d9..1ed5568680ba2f49e2dacf9fb6a4c3b338ab786e 100644 (file)
@@ -880,7 +880,6 @@ ALTER TABLE "RULES_PROFILES" ADD CONSTRAINT "PK_RULES_PROFILES" PRIMARY KEY("ID"
 CREATE UNIQUE INDEX "UNIQ_QPROF_KEY" ON "RULES_PROFILES"("KEE");
 
 CREATE TABLE "SNAPSHOTS"(
-    "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
     "UUID" VARCHAR(50) NOT NULL,
     "COMPONENT_UUID" VARCHAR(50) NOT NULL,
     "STATUS" VARCHAR(4) DEFAULT 'U' NOT NULL,
@@ -907,7 +906,7 @@ CREATE TABLE "SNAPSHOTS"(
     "PERIOD5_DATE" BIGINT,
     "CREATED_AT" BIGINT
 );
-ALTER TABLE "SNAPSHOTS" ADD CONSTRAINT "PK_SNAPSHOTS" PRIMARY KEY("ID");
+ALTER TABLE "SNAPSHOTS" ADD CONSTRAINT "PK_SNAPSHOTS" PRIMARY KEY("UUID");
 CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS"("UUID");
 CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS"("COMPONENT_UUID");
 
index 13510666665b91a2d76deb776e34531ad7596073..da73a802f49a8c6a00cb1a6092b2a050c5d440fa 100644 (file)
@@ -92,7 +92,6 @@ public class SnapshotDaoTest {
       .setRevision("sha1"));
 
     SnapshotDto result = underTest.selectByUuid(db.getSession(), "ABCD").get();
-    assertThat(result.getId()).isNotNull();
     assertThat(result.getUuid()).isEqualTo("ABCD");
     assertThat(result.getComponentUuid()).isEqualTo(project.uuid());
     assertThat(result.getStatus()).isEqualTo("P");
@@ -165,7 +164,7 @@ public class SnapshotDaoTest {
 
     List<SnapshotDto> result = underTest.selectLastAnalysesByRootComponentUuids(dbSession, newArrayList(firstProject.uuid(), secondProject.uuid()));
 
-    assertThat(result).extracting(SnapshotDto::getId).containsOnly(lastSnapshotOfFirstProject.getId(), lastSnapshotOfSecondProject.getId());
+    assertThat(result).extracting(SnapshotDto::getUuid).containsOnly(lastSnapshotOfFirstProject.getUuid(), lastSnapshotOfSecondProject.getUuid());
   }
 
   @Test
@@ -373,7 +372,6 @@ public class SnapshotDaoTest {
       .setBuildDate(1500000000006L)
       .setCreatedAt(1403042400000L));
 
-    assertThat(dto.getId()).isNotNull();
     assertThat(dto.getUuid()).isNotNull();
     assertThat(dto.getComponentUuid()).isEqualTo(project.uuid());
     assertThat(dto.getStatus()).isEqualTo("P");
index d97c4da796cceab2cadb1d6e1162e52b301eaf4f..706e9bfa13625eb4ab2b6cb52fb19c6d01cbc432 100644 (file)
@@ -35,7 +35,6 @@ public class SnapshotDtoTest {
   @Test
   public void test_getter_and_setter() {
     SnapshotDto snapshotDto = new SnapshotDto()
-      .setId(10L)
       .setBuildDate(parseDate("2014-07-02").getTime())
       .setComponentUuid("uuid_21")
       .setLast(true)
@@ -45,7 +44,6 @@ public class SnapshotDtoTest {
       .setPeriodParam("param1")
       .setPeriodDate(parseDate("2014-06-01").getTime());
 
-    assertThat(snapshotDto.getId()).isEqualTo(10L);
     assertThat(snapshotDto.getBuildDate()).isEqualTo(parseDate("2014-07-02").getTime());
     assertThat(snapshotDto.getComponentUuid()).isEqualTo("uuid_21");
     assertThat(snapshotDto.getLast()).isTrue();
index b1a8614e68309125afbaf5ba9c8122864e20f64c..2634468b5f4eee79147494a76b2e7670b2554f7d 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.db.purge;
 
-import com.google.common.collect.ImmutableList;
 import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
@@ -27,7 +26,6 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Random;
 import java.util.function.Consumer;
-import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import java.util.stream.Stream;
 import org.junit.After;
@@ -56,8 +54,8 @@ import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 
 import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Arrays.asList;
 import static java.util.Collections.singletonList;
-import static java.util.stream.Collectors.toList;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.db.component.ComponentTesting.newBranchDto;
@@ -101,18 +99,18 @@ public class PurgeCommandsTest {
     SnapshotDto analysis2 = dbTester.components().insertSnapshot(project);
     SnapshotDto analysis3 = dbTester.components().insertSnapshot(project);
     SnapshotDto analysis4 = dbTester.components().insertSnapshot(project);
-    int count = 1 + random.nextInt(12);
-    for (SnapshotDto analysis : Arrays.asList(analysis1, analysis2, analysis3, analysis4)) {
+    int count = 8;
+    for (SnapshotDto analysis : asList(analysis1, analysis2, analysis3, analysis4)) {
       IntStream.range(0, count).forEach(i -> insertDuplication(project, analysis));
     }
 
-    underTest.purgeAnalyses(ImmutableList.of(analysis1.getUuid()));
+    underTest.purgeAnalyses(singletonList(analysis1.getUuid()));
     assertThat(countDuplications(analysis1)).isZero();
     assertThat(countDuplications(analysis2)).isEqualTo(count);
     assertThat(countDuplications(analysis3)).isEqualTo(count);
     assertThat(countDuplications(analysis4)).isEqualTo(count);
 
-    underTest.purgeAnalyses(ImmutableList.of(analysis1.getUuid(), analysis3.getUuid(), analysis4.getUuid()));
+    underTest.purgeAnalyses(asList(analysis1.getUuid(), analysis3.getUuid(), analysis4.getUuid()));
     assertThat(countDuplications(analysis1)).isZero();
     assertThat(countDuplications(analysis2)).isEqualTo(count);
     assertThat(countDuplications(analysis3)).isZero();
@@ -155,7 +153,7 @@ public class PurgeCommandsTest {
   public void deleteComponents_delete_tree_of_components_of_a_view(OrganizationDto organizationDto, ComponentDto view) {
     dbTester.organizations().insert(organizationDto);
     dbTester.components().insertComponent(view);
-    ComponentDto otherView = dbTester.components().insertView(organizationDto);
+    ComponentDto otherView = dbTester.components().insertPrivatePortfolio(organizationDto);
     Stream.of(view, otherView).forEach(vw -> {
       dbTester.components().insertSubView(vw);
       dbTester.components().insertComponent(newProjectCopy(dbTester.components().insertPrivateProject(), vw));
@@ -231,7 +229,7 @@ public class PurgeCommandsTest {
   public void deleteAnalyses_by_rootUuid_deletes_event_component_changes(ComponentDto projectOrView) {
     dbTester.components().insertComponent(projectOrView);
     ComponentDto otherProject = dbTester.components().insertPrivateProject();
-    int count = 1 + new Random().nextInt(20);
+    int count = 5;
     IntStream.range(0, count).forEach(i -> {
       insertRandomEventComponentChange(projectOrView);
       insertRandomEventComponentChange(otherProject);
@@ -252,7 +250,7 @@ public class PurgeCommandsTest {
     ComponentDto otherProject = dbTester.components().insertPrivateProject();
     SnapshotDto otherAnalysis1 = dbTester.components().insertSnapshot(otherProject);
     SnapshotDto otherAnalysis2 = dbTester.components().insertSnapshot(otherProject);
-    int count = 1 + new Random().nextInt(20);
+    int count = 7;
     IntStream.range(0, count).forEach(i -> {
       dbTester.events().insertEvent(analysis1);
       dbTester.events().insertEvent(analysis2);
@@ -279,7 +277,7 @@ public class PurgeCommandsTest {
     ComponentDto otherProject = dbTester.components().insertPrivateProject();
     SnapshotDto otherAnalysis1 = dbTester.components().insertSnapshot(otherProject);
     SnapshotDto otherAnalysis2 = dbTester.components().insertSnapshot(otherProject);
-    int count = 1 + new Random().nextInt(20);
+    int count = 5;
     Stream.of(metric1, metric2)
       .forEach(metric -> {
         IntStream.range(0, count).forEach(i -> {
@@ -307,7 +305,7 @@ public class PurgeCommandsTest {
     ComponentDto otherProject = dbTester.components().insertPrivateProject();
     SnapshotDto otherAnalysis1 = dbTester.components().insertSnapshot(otherProject);
     SnapshotDto otherAnalysis2 = dbTester.components().insertSnapshot(otherProject);
-    int count = 1 + new Random().nextInt(20);
+    int count = 5;
     IntStream.range(0, count).forEach(i -> {
       insertRandomAnalysisProperty(analysis1);
       insertRandomAnalysisProperty(analysis2);
@@ -353,19 +351,20 @@ public class PurgeCommandsTest {
   @UseDataProvider("projectsAndViews")
   public void deleteAnalyses_by_analyses_deletes_specified_analysis(ComponentDto projectOrView) {
     dbTester.components().insertComponent(projectOrView);
-    List<SnapshotDto> analyses = IntStream.range(0, 5 + random.nextInt(10))
-      .mapToObj(i -> dbTester.components().insertSnapshot(projectOrView, randomLastAndStatus()))
-      .collect(toList());
+    SnapshotDto analysis1 = dbTester.components().insertSnapshot(projectOrView, s -> s.setStatus(STATUS_PROCESSED));
+    SnapshotDto analysis2 = dbTester.components().insertSnapshot(projectOrView, s -> s.setStatus(STATUS_PROCESSED));
+    SnapshotDto analysis3 = dbTester.components().insertSnapshot(projectOrView, s -> s.setStatus(STATUS_UNPROCESSED));
+    SnapshotDto analysis4 = dbTester.components().insertSnapshot(projectOrView, s -> s.setStatus(STATUS_UNPROCESSED));
 
-    underTest.deleteAnalyses(singletonList(analyses.get(0).getUuid()));
+    underTest.deleteAnalyses(singletonList(analysis1.getUuid()));
     assertThat(uuidsOfAnalysesOfRoot(projectOrView))
-      .containsOnly(analyses.stream().skip(1).map(SnapshotDto::getUuid).toArray(String[]::new));
+      .containsOnly(analysis2.getUuid(), analysis3.getUuid(), analysis4.getUuid());
 
-    underTest.deleteAnalyses(analyses.stream().map(SnapshotDto::getUuid).skip(1).limit(3).collect(Collectors.toList()));
+    underTest.deleteAnalyses(asList(analysis2.getUuid(), analysis3.getUuid()));
     assertThat(uuidsOfAnalysesOfRoot(projectOrView))
-      .containsOnly(analyses.stream().skip(4).map(SnapshotDto::getUuid).toArray(String[]::new));
+      .containsOnly(analysis4.getUuid());
 
-    underTest.deleteAnalyses(analyses.stream().map(SnapshotDto::getUuid).collect(Collectors.toList()));
+    underTest.deleteAnalyses(asList(analysis1.getUuid(), analysis2.getUuid(), analysis3.getUuid(), analysis4.getUuid()));
     assertThat(uuidsOfAnalysesOfRoot(projectOrView)).isEmpty();
   }
 
@@ -381,7 +380,7 @@ public class PurgeCommandsTest {
     dbTester.components().insertComponent(projectOrView);
     SnapshotDto analysis = dbTester.components().insertSnapshot(projectOrView, randomLastAndStatus());
     SnapshotDto otherAnalysis = dbTester.components().insertSnapshot(projectOrView);
-    int count = 1 + new Random().nextInt(20);
+    int count = 5;
     IntStream.range(0, count).forEach(i -> {
       insertRandomEventComponentChange(analysis);
       insertRandomEventComponentChange(otherAnalysis);
@@ -399,7 +398,7 @@ public class PurgeCommandsTest {
     dbTester.components().insertComponent(projectOrView);
     SnapshotDto analysis = dbTester.components().insertSnapshot(projectOrView, randomLastAndStatus());
     SnapshotDto otherAnalysis = dbTester.components().insertSnapshot(projectOrView);
-    int count = 1 + new Random().nextInt(20);
+    int count = 5;
     IntStream.range(0, count).forEach(i -> {
       dbTester.events().insertEvent(analysis);
       dbTester.events().insertEvent(otherAnalysis);
@@ -419,7 +418,7 @@ public class PurgeCommandsTest {
     dbTester.components().insertComponent(projectOrView);
     SnapshotDto analysis = dbTester.components().insertSnapshot(projectOrView, randomLastAndStatus());
     SnapshotDto otherAnalysis = dbTester.components().insertSnapshot(projectOrView);
-    int count = 1 + new Random().nextInt(20);
+    int count = 5;
     Stream.of(metric1, metric2)
       .forEach(metric -> {
         IntStream.range(0, count).forEach(i -> {
@@ -440,7 +439,7 @@ public class PurgeCommandsTest {
     dbTester.components().insertComponent(projectOrView);
     SnapshotDto analysis = dbTester.components().insertSnapshot(projectOrView, randomLastAndStatus());
     SnapshotDto otherAnalysis = dbTester.components().insertSnapshot(projectOrView);
-    int count = 1 + new Random().nextInt(20);
+    int count = 4;
     IntStream.range(0, count).forEach(i -> {
       insertRandomAnalysisProperty(analysis);
       insertRandomAnalysisProperty(otherAnalysis);
@@ -461,7 +460,7 @@ public class PurgeCommandsTest {
     ComponentDto file = dbTester.components().insertComponent(newFileDto(projectOrView));
     ComponentDto otherProject = dbTester.components().insertPrivateProject();
     ComponentDto otherFile = dbTester.components().insertComponent(newFileDto(otherProject));
-    int count = 5 + random.nextInt(10);
+    int count = 5;
     IntStream.range(0, count).forEach(i -> {
       Stream.of(rule1, rule2).forEach(rule -> {
         dbTester.issues().insertIssue(t -> t.setRule(rule).setProject(projectOrView).setComponent(projectOrView));
@@ -483,7 +482,7 @@ public class PurgeCommandsTest {
     RuleDefinitionDto rule = dbTester.rules().insert();
     dbTester.components().insertComponent(projectOrView);
     ComponentDto file = dbTester.components().insertComponent(newFileDto(projectOrView));
-    int count = 5 + random.nextInt(10);
+    int count = 5;
     IntStream.range(0, count).forEach(i -> {
       IssueDto issue = dbTester.issues().insertIssue(t -> t.setRule(rule).setProject(projectOrView).setComponent(projectOrView));
       dbTester.issues().insertChange(issue);
@@ -542,19 +541,19 @@ public class PurgeCommandsTest {
     BranchDto branch = newBranchDto(project);
     dbTester.components().insertProjectBranch(project, branch);
 
-    //global settings
+    // global settings
     dbTester.newCodePeriods().insert(NewCodePeriodType.PREVIOUS_VERSION, null);
 
-    //project settings
+    // project settings
     dbTester.newCodePeriods().insert(project.uuid(), NewCodePeriodType.NUMBER_OF_DAYS, "20");
 
-    //branch settings
+    // branch settings
     dbTester.newCodePeriods().insert(project.uuid(), branch.getUuid(), NewCodePeriodType.NUMBER_OF_DAYS, "1");
 
     PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
     purgeCommands.deleteNewCodePeriods(branch.getUuid());
 
-    //should delete branch settings only
+    // should delete branch settings only
     assertThat(dbTester.countRowsOfTable("new_code_periods")).isEqualTo(2);
   }
 
@@ -565,19 +564,19 @@ public class PurgeCommandsTest {
     BranchDto branch = newBranchDto(project);
     dbTester.components().insertProjectBranch(project, branch);
 
-    //global settings
+    // global settings
     dbTester.newCodePeriods().insert(NewCodePeriodType.PREVIOUS_VERSION, null);
 
-    //project settings
+    // project settings
     dbTester.newCodePeriods().insert(project.uuid(), NewCodePeriodType.NUMBER_OF_DAYS, "20");
 
-    //branch settings
+    // branch settings
     dbTester.newCodePeriods().insert(project.uuid(), branch.getUuid(), NewCodePeriodType.NUMBER_OF_DAYS, "1");
 
     PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
     purgeCommands.deleteNewCodePeriods(project.uuid());
 
-    //should delete branch and project settings only
+    // should delete branch and project settings only
     assertThat(dbTester.countRowsOfTable("new_code_periods")).isEqualTo(1);
   }
 
@@ -588,19 +587,19 @@ public class PurgeCommandsTest {
     BranchDto branch = newBranchDto(project);
     dbTester.components().insertProjectBranch(project, branch);
 
-    //global settings
+    // global settings
     dbTester.newCodePeriods().insert(NewCodePeriodType.PREVIOUS_VERSION, null);
 
-    //project settings
+    // project settings
     dbTester.newCodePeriods().insert(project.uuid(), NewCodePeriodType.NUMBER_OF_DAYS, "20");
 
-    //branch settings
+    // branch settings
     dbTester.newCodePeriods().insert(project.uuid(), branch.getUuid(), NewCodePeriodType.NUMBER_OF_DAYS, "1");
 
     PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
     purgeCommands.deleteNewCodePeriods(null);
 
-    //should delete branch and project settings only
+    // should delete branch and project settings only
     assertThat(dbTester.countRowsOfTable("new_code_periods")).isEqualTo(3);
   }
 
index 11e9b3e32eba6ee005d054b44c7f18a1518ada98..6ef1af9804d6ad73c2a719a25982f686961af8e7 100644 (file)
@@ -19,7 +19,6 @@
  */
 package org.sonar.db.purge;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import java.io.ByteArrayInputStream;
 import java.time.LocalDateTime;
@@ -305,11 +304,11 @@ public class PurgeDaoTest {
     ComponentDto otherProject = db.components().insertPrivateProject();
     SnapshotDto otherAnalysis1 = db.components().insertSnapshot(otherProject);
 
-    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(analysis1.getUuid()));
+    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(analysis1.getUuid()));
 
     assertThat(uuidsIn("snapshots")).containsOnly(analysis2.getUuid(), analysis3.getUuid(), otherAnalysis1.getUuid());
 
-    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), ImmutableList.of(analysis1.getUuid(), analysis3.getUuid(), otherAnalysis1.getUuid()));
+    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), asList(analysis1.getUuid(), analysis3.getUuid(), otherAnalysis1.getUuid()));
 
     assertThat(uuidsIn("snapshots")).containsOnly(analysis2.getUuid());
   }
@@ -344,7 +343,7 @@ public class PurgeDaoTest {
     assertThat(uuidsIn("events"))
       .containsOnly(projectEvent1.getUuid(), projectEvent2.getUuid(), projectEvent3.getUuid());
 
-    underTest.deleteAnalyses(dbSession, new PurgeProfiler(),  singletonList(projectAnalysis1.getUuid()));
+    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis1.getUuid()));
     assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
       .containsOnly(projectAnalysis2.getUuid());
     assertThat(db.countRowsOfTable("event_component_changes"))
@@ -360,7 +359,7 @@ public class PurgeDaoTest {
     assertThat(uuidsIn("events"))
       .containsOnly(projectEvent2.getUuid(), projectEvent3.getUuid());
 
-    underTest.deleteAnalyses(dbSession, new PurgeProfiler(),  singletonList(projectAnalysis3.getUuid()));
+    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis3.getUuid()));
     assertThat(uuidsIn("event_component_changes", "event_analysis_uuid"))
       .containsOnly(projectAnalysis2.getUuid());
     assertThat(db.countRowsOfTable("event_component_changes"))
@@ -368,7 +367,7 @@ public class PurgeDaoTest {
     assertThat(uuidsIn("events"))
       .containsOnly(projectEvent2.getUuid());
 
-    underTest.deleteAnalyses(dbSession, new PurgeProfiler(),  singletonList(projectAnalysis2.getUuid()));
+    underTest.deleteAnalyses(dbSession, new PurgeProfiler(), singletonList(projectAnalysis2.getUuid()));
     assertThat(db.countRowsOfTable("event_component_changes"))
       .isZero();
     assertThat(db.countRowsOfTable("events"))
@@ -1670,4 +1669,5 @@ public class PurgeDaoTest {
       .stream()
       .map(t -> (String) t.get("UUID"));
   }
+
 }
index 0c18f91229e3907c9c9aafce73a26a5d355e29e8..61200c8a12fd0a8c50dfe960bd3243259e6c3934 100644 (file)
@@ -45,8 +45,8 @@ public class DefaultPeriodCleanerTest {
     PurgeDao dao = mock(PurgeDao.class);
     DbSession session = mock(DbSession.class);
     when(dao.selectPurgeableAnalyses("uuid_123", session)).thenReturn(Arrays.asList(
-        new PurgeableAnalysisDto().setAnalysisId(999).setAnalysisUuid("u999").setDate(System2.INSTANCE.now()),
-        new PurgeableAnalysisDto().setAnalysisId(456).setAnalysisUuid("u456").setDate(System2.INSTANCE.now())
+        new PurgeableAnalysisDto().setAnalysisUuid("u999").setDate(System2.INSTANCE.now()),
+        new PurgeableAnalysisDto().setAnalysisUuid("u456").setDate(System2.INSTANCE.now())
         ));
     Filter filter1 = newFirstSnapshotInListFilter();
     Filter filter2 = newFirstSnapshotInListFilter();
@@ -59,7 +59,7 @@ public class DefaultPeriodCleanerTest {
     inOrder.verify(filter1).log();
     inOrder.verify(dao, times(1)).deleteAnalyses(eq(session), eq(profiler), eq(ImmutableList.of("u999")));
     inOrder.verify(filter2).log();
-    inOrder.verify(dao, times(1)).deleteAnalyses(eq(session), eq(profiler), eq(ImmutableList.of( "u456")));
+    inOrder.verify(dao, times(1)).deleteAnalyses(eq(session), eq(profiler), eq(ImmutableList.of("u456")));
     inOrder.verifyNoMoreInteractions();
   }
 
index bf8d2d0a5931891e331f1ffd4c7504181979a4d4..e5b9a03f46a519221cf7059566a706cbfff80bba 100644 (file)
@@ -33,6 +33,9 @@ import org.sonar.server.platform.db.migration.version.v83.notifications.DropIdCo
 import org.sonar.server.platform.db.migration.version.v83.notifications.DropPrimaryKeyOnIdColumnOfNotificationTable;
 import org.sonar.server.platform.db.migration.version.v83.notifications.MakeNotificationUuidAndCreatedAtColumnsNotNullable;
 import org.sonar.server.platform.db.migration.version.v83.notifications.PopulateNotificationUuidAndCreatedAt;
+import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.AddPrimaryKeyOnUuidColumnOfSnapshotsTable;
+import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.DropIdColumnOfSnapshotsTable;
+import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.DropPrimaryKeyOnIdColumnOfSnapshotsTable;
 
 public class DbVersion83 implements DbVersion {
   @Override
@@ -69,6 +72,11 @@ public class DbVersion83 implements DbVersion {
       .add(3410, "Add primary key on 'KEE' column of 'ISSUES' table", AddPrimaryKeyOnKeeColumnOfIssuesTable.class)
       .add(3411, "Drop column 'ID' of 'ISSUES' table", DropIdColumnOfIssuesTable.class)
 
+      // Migration on SNAPSHOTS table
+      .add(3412, "Drop primary key on 'ID' column of 'SNAPSHOTS' table", DropPrimaryKeyOnIdColumnOfSnapshotsTable.class)
+      .add(3413, "Add primary key on 'UUID' column of 'SNAPSHOTS' table", AddPrimaryKeyOnUuidColumnOfSnapshotsTable.class)
+      .add(3414, "Drop column 'ID' of 'SNAPSHOTS' table", DropIdColumnOfSnapshotsTable.class)
+
     ;
   }
 }
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/AddPrimaryKeyOnUuidColumnOfSnapshotsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/AddPrimaryKeyOnUuidColumnOfSnapshotsTable.java
new file mode 100644 (file)
index 0000000..75add59
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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.server.platform.db.migration.version.v83.snapshots.issues;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.AddPrimaryKeyBuilder;
+
+public class AddPrimaryKeyOnUuidColumnOfSnapshotsTable extends DdlChange {
+
+  public AddPrimaryKeyOnUuidColumnOfSnapshotsTable(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddPrimaryKeyBuilder("snapshots", "uuid").build());
+  }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/DropIdColumnOfSnapshotsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/DropIdColumnOfSnapshotsTable.java
new file mode 100644 (file)
index 0000000..64d9b3e
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.server.platform.db.migration.version.v83.snapshots.issues;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.sql.DropColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+public class DropIdColumnOfSnapshotsTable extends DdlChange {
+
+  private Database db;
+
+  public DropIdColumnOfSnapshotsTable(Database db) {
+    super(db);
+    this.db = db;
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new DropColumnsBuilder(db.getDialect(), "snapshots", "id").build());
+  }
+
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/DropPrimaryKeyOnIdColumnOfSnapshotsTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v83/snapshots/issues/DropPrimaryKeyOnIdColumnOfSnapshotsTable.java
new file mode 100644 (file)
index 0000000..a309537
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * 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.server.platform.db.migration.version.v83.snapshots.issues;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
+
+public class DropPrimaryKeyOnIdColumnOfSnapshotsTable extends DdlChange {
+
+  private final DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator;
+
+  public DropPrimaryKeyOnIdColumnOfSnapshotsTable(Database db, DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator) {
+    super(db);
+    this.dropPrimaryKeySqlGenerator = dropPrimaryKeySqlGenerator;
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(dropPrimaryKeySqlGenerator.generate("snapshots", "snapshots","id"));
+  }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest.java
new file mode 100644 (file)
index 0000000..8301a65
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.server.platform.db.migration.version.v83.snapshots;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.AddPrimaryKeyOnUuidColumnOfSnapshotsTable;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest {
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest.class, "schema.sql");
+
+  private AddPrimaryKeyOnUuidColumnOfSnapshotsTable underTest = new AddPrimaryKeyOnUuidColumnOfSnapshotsTable(db.database());
+
+  @Test
+  public void execute() throws SQLException {
+    underTest.execute();
+
+    db.assertPrimaryKey("snapshots", "pk_snapshots", "uuid");
+  }
+
+  @Test
+  public void migration_is_not_re_entrant() throws SQLException {
+    underTest.execute();
+
+    assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+  }
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/DropIdColumnOfSnapshotsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/DropIdColumnOfSnapshotsTableTest.java
new file mode 100644 (file)
index 0000000..8cdf3ed
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * 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.server.platform.db.migration.version.v83.snapshots;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.DropIdColumnOfSnapshotsTable;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class DropIdColumnOfSnapshotsTableTest {
+
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(DropIdColumnOfSnapshotsTableTest.class, "schema.sql");
+
+  private DropIdColumnOfSnapshotsTable underTest = new DropIdColumnOfSnapshotsTable(db.database());
+
+  @Test
+  public void execute() throws SQLException {
+    underTest.execute();
+
+    db.assertColumnDoesNotExist("snapshots", "id");
+  }
+
+  @Test
+  public void migration_is_not_re_entrant() throws SQLException {
+    underTest.execute();
+
+    assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+  }
+
+}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/DropPrimaryKeyOnIdColumnOfSnapshotsTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v83/snapshots/DropPrimaryKeyOnIdColumnOfSnapshotsTableTest.java
new file mode 100644 (file)
index 0000000..beebc70
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * 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.server.platform.db.migration.version.v83.snapshots;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.version.v83.snapshots.issues.DropPrimaryKeyOnIdColumnOfSnapshotsTable;
+import org.sonar.server.platform.db.migration.version.v83.util.DropPrimaryKeySqlGenerator;
+import org.sonar.server.platform.db.migration.version.v83.util.GetConstraintHelper;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+public class DropPrimaryKeyOnIdColumnOfSnapshotsTableTest {
+
+  private static final String TABLE_NAME = "snapshots";
+  @Rule
+  public CoreDbTester db = CoreDbTester.createForSchema(DropPrimaryKeyOnIdColumnOfSnapshotsTableTest.class, "schema.sql");
+
+  private DropPrimaryKeySqlGenerator dropPrimaryKeySqlGenerator = new DropPrimaryKeySqlGenerator(db.database(), new GetConstraintHelper(db.database()));
+
+  private DropPrimaryKeyOnIdColumnOfSnapshotsTable underTest = new DropPrimaryKeyOnIdColumnOfSnapshotsTable(db.database(), dropPrimaryKeySqlGenerator);
+
+  @Test
+  public void execute() throws SQLException {
+    underTest.execute();
+
+    db.assertNoPrimaryKey(TABLE_NAME);
+  }
+
+  @Test
+  public void migration_is_not_re_entrant() throws SQLException {
+    underTest.execute();
+
+    assertThatThrownBy(() -> underTest.execute()).isInstanceOf(IllegalStateException.class);
+  }
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/AddPrimaryKeyOnUuidColumnOfSnapshotsTableTest/schema.sql
new file mode 100644 (file)
index 0000000..dcc23f6
--- /dev/null
@@ -0,0 +1,30 @@
+CREATE TABLE "SNAPSHOTS"(
+    "ID" INTEGER NOT NULL,
+    "UUID" VARCHAR(50) NOT NULL,
+    "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+    "STATUS" VARCHAR(4) DEFAULT 'U' NOT NULL,
+    "ISLAST" BOOLEAN DEFAULT FALSE NOT NULL,
+    "VERSION" VARCHAR(500),
+    "PURGE_STATUS" INTEGER,
+    "BUILD_STRING" VARCHAR(100),
+    "REVISION" VARCHAR(100),
+    "BUILD_DATE" BIGINT,
+    "PERIOD1_MODE" VARCHAR(100),
+    "PERIOD1_PARAM" VARCHAR(100),
+    "PERIOD2_MODE" VARCHAR(100),
+    "PERIOD2_PARAM" VARCHAR(100),
+    "PERIOD3_MODE" VARCHAR(100),
+    "PERIOD3_PARAM" VARCHAR(100),
+    "PERIOD4_MODE" VARCHAR(100),
+    "PERIOD4_PARAM" VARCHAR(100),
+    "PERIOD5_MODE" VARCHAR(100),
+    "PERIOD5_PARAM" VARCHAR(100),
+    "PERIOD1_DATE" BIGINT,
+    "PERIOD2_DATE" BIGINT,
+    "PERIOD3_DATE" BIGINT,
+    "PERIOD4_DATE" BIGINT,
+    "PERIOD5_DATE" BIGINT,
+    "CREATED_AT" BIGINT
+);
+CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS"("UUID");
+CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS"("COMPONENT_UUID");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/DropIdColumnOfSnapshotsTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/DropIdColumnOfSnapshotsTableTest/schema.sql
new file mode 100644 (file)
index 0000000..c189140
--- /dev/null
@@ -0,0 +1,31 @@
+CREATE TABLE "SNAPSHOTS"(
+    "ID" INTEGER NOT NULL,
+    "UUID" VARCHAR(50) NOT NULL,
+    "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+    "STATUS" VARCHAR(4) DEFAULT 'U' NOT NULL,
+    "ISLAST" BOOLEAN DEFAULT FALSE NOT NULL,
+    "VERSION" VARCHAR(500),
+    "PURGE_STATUS" INTEGER,
+    "BUILD_STRING" VARCHAR(100),
+    "REVISION" VARCHAR(100),
+    "BUILD_DATE" BIGINT,
+    "PERIOD1_MODE" VARCHAR(100),
+    "PERIOD1_PARAM" VARCHAR(100),
+    "PERIOD2_MODE" VARCHAR(100),
+    "PERIOD2_PARAM" VARCHAR(100),
+    "PERIOD3_MODE" VARCHAR(100),
+    "PERIOD3_PARAM" VARCHAR(100),
+    "PERIOD4_MODE" VARCHAR(100),
+    "PERIOD4_PARAM" VARCHAR(100),
+    "PERIOD5_MODE" VARCHAR(100),
+    "PERIOD5_PARAM" VARCHAR(100),
+    "PERIOD1_DATE" BIGINT,
+    "PERIOD2_DATE" BIGINT,
+    "PERIOD3_DATE" BIGINT,
+    "PERIOD4_DATE" BIGINT,
+    "PERIOD5_DATE" BIGINT,
+    "CREATED_AT" BIGINT
+);
+ALTER TABLE "SNAPSHOTS" ADD CONSTRAINT "PK_SNAPSHOTS" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS"("UUID");
+CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS"("COMPONENT_UUID");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/DropPrimaryKeyOnIdColumnOfSnapshotsTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v83/snapshots/DropPrimaryKeyOnIdColumnOfSnapshotsTableTest/schema.sql
new file mode 100644 (file)
index 0000000..3d3e269
--- /dev/null
@@ -0,0 +1,31 @@
+CREATE TABLE "SNAPSHOTS"(
+    "ID" INTEGER NOT NULL AUTO_INCREMENT (1,1),
+    "UUID" VARCHAR(50) NOT NULL,
+    "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+    "STATUS" VARCHAR(4) DEFAULT 'U' NOT NULL,
+    "ISLAST" BOOLEAN DEFAULT FALSE NOT NULL,
+    "VERSION" VARCHAR(500),
+    "PURGE_STATUS" INTEGER,
+    "BUILD_STRING" VARCHAR(100),
+    "REVISION" VARCHAR(100),
+    "BUILD_DATE" BIGINT,
+    "PERIOD1_MODE" VARCHAR(100),
+    "PERIOD1_PARAM" VARCHAR(100),
+    "PERIOD2_MODE" VARCHAR(100),
+    "PERIOD2_PARAM" VARCHAR(100),
+    "PERIOD3_MODE" VARCHAR(100),
+    "PERIOD3_PARAM" VARCHAR(100),
+    "PERIOD4_MODE" VARCHAR(100),
+    "PERIOD4_PARAM" VARCHAR(100),
+    "PERIOD5_MODE" VARCHAR(100),
+    "PERIOD5_PARAM" VARCHAR(100),
+    "PERIOD1_DATE" BIGINT,
+    "PERIOD2_DATE" BIGINT,
+    "PERIOD3_DATE" BIGINT,
+    "PERIOD4_DATE" BIGINT,
+    "PERIOD5_DATE" BIGINT,
+    "CREATED_AT" BIGINT
+);
+ALTER TABLE "SNAPSHOTS" ADD CONSTRAINT "PK_SNAPSHOTS" PRIMARY KEY("ID");
+CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS"("UUID");
+CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS"("COMPONENT_UUID");