]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11631 Persist sonar.buildString in database
authorJanos Gyerik <janos.gyerik@sonarsource.com>
Thu, 14 Mar 2019 14:28:05 +0000 (15:28 +0100)
committerSonarTech <sonartech@sonarsource.com>
Tue, 19 Mar 2019 19:21:27 +0000 (20:21 +0100)
21 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectAttributes.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStep.java
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistAnalysisStep.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentImplTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ComponentTreeBuilderTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReportComponent.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java
server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistAnalysisStepTest.java
server/sonar-db-core/src/main/resources/org/sonar/db/version/schema-h2.ddl
server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDto.java
server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeCommandsTest/shouldPurgeAnalysis-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldDeleteAbortedBuilds-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldDeleteAnalyses-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldDeleteHistoricalDataOfDirectoriesAndFiles-result.xml
server/sonar-db-dao/src/test/resources/org/sonar/db/purge/PurgeDaoTest/shouldPurgeProject-result.xml
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshot.java [new file with mode: 0644]
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v77/DbVersion77.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshotTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v77/DbVersion77Test.java
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshotTest/snapshots.sql [new file with mode: 0644]

index 5d6e071602832ccda7534b796e1485586edd5a78..0acceca325558a0668a4ac62eb16707f7aadacef 100644 (file)
@@ -27,15 +27,18 @@ import static java.util.Objects.requireNonNull;
 public class ProjectAttributes {
   private final String projectVersion;
   private final String codePeriodVersion;
+  private final String buildString;
 
-  public ProjectAttributes(@Nullable String projectVersion, String codePeriodVersion) {
+  public ProjectAttributes(@Nullable String projectVersion, String codePeriodVersion, String buildString) {
     this.projectVersion = projectVersion;
     this.codePeriodVersion = requireNonNull(codePeriodVersion, "codePeriod version can't be null");
+    this.buildString = buildString;
   }
 
   public ProjectAttributes(ProjectAttributes projectAttributes) {
     this.projectVersion = projectAttributes.projectVersion;
     this.codePeriodVersion = projectAttributes.codePeriodVersion;
+    this.buildString = projectAttributes.buildString;
   }
 
   public Optional<String> getProjectVersion() {
@@ -46,11 +49,16 @@ public class ProjectAttributes {
     return codePeriodVersion;
   }
 
+  public Optional<String> getBuildString() {
+    return Optional.ofNullable(buildString);
+  }
+
   @Override
   public String toString() {
     return "ProjectAttributes{" +
       "projectVersion='" + projectVersion + '\'' +
       "codePeriodVersion='" + codePeriodVersion + '\'' +
+      "buildString='" + buildString + '\'' +
       '}';
   }
 }
index 1fd3bcaa91ecb3ad7bdc9425f010adc5ecc6283c..1bd1d95f9eede0de12f9a020f1d8dc159d51d476 100644 (file)
@@ -113,7 +113,8 @@ public class BuildComponentTreeStep implements ComputationStep {
   private static ProjectAttributes createProjectAttributes(ScannerReport.Metadata metadata, @Nullable SnapshotDto baseAnalysis) {
     String projectVersion = trimToNull(metadata.getProjectVersion());
     String codePeriodVersion = computeCodePeriodVersion(metadata.getCodePeriodVersion(), projectVersion, baseAnalysis);
-    return new ProjectAttributes(projectVersion, codePeriodVersion);
+    String buildString = trimToNull(metadata.getBuildString());
+    return new ProjectAttributes(projectVersion, codePeriodVersion, buildString);
   }
 
   private static String computeCodePeriodVersion(String rawCodePeriodVersion, @Nullable String projectVersion, @Nullable SnapshotDto baseAnalysis) {
index d8cfa4c067d6e0654a1173089710065bcf098592..c693268c341765629677219cbbbf85d4b4da3f32 100644 (file)
@@ -104,10 +104,12 @@ public class PersistAnalysisStep implements ComputationStep {
       String componentUuid = component.getUuid();
       String codePeriodVersion = component.getType() == PROJECT ? component.getProjectAttributes().getCodePeriodVersion() : null;
       String projectVersion = component.getType() == PROJECT ? component.getProjectAttributes().getProjectVersion().orElse(null) : null;
+      String buildString = component.getType() == PROJECT ? component.getProjectAttributes().getBuildString().orElse(null) : null;
       return new SnapshotDto()
         .setUuid(snapshotUuid)
         .setCodePeriodVersion(codePeriodVersion)
         .setProjectVersion(projectVersion)
+        .setBuildString(buildString)
         .setComponentUuid(componentUuid)
         .setLast(false)
         .setStatus(SnapshotDto.STATUS_UNPROCESSED)
index cc59ac0afdb2809336a9b7abcb6608a2931323f6..ce49e193645641c87207e87434236e59902397b8 100644 (file)
@@ -21,12 +21,14 @@ package org.sonar.ce.task.projectanalysis.component;
 
 import java.util.Arrays;
 import java.util.Collections;
+import org.apache.commons.lang.RandomStringUtils;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.ce.task.projectanalysis.component.Component.Status;
 
 import static com.google.common.base.Strings.repeat;
+import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
 import static org.sonar.ce.task.projectanalysis.component.Component.Type.FILE;
@@ -246,7 +248,8 @@ public class ComponentImplTest {
       .setUuid("uuid_" + dbKey)
       .setReportAttributes(ReportAttributes.newBuilder(dbKey.hashCode()).build());
     if (type == PROJECT) {
-      builder.setProjectAttributes(new ProjectAttributes(null, "version_1"));
+      String buildString = randomAlphabetic(15);
+      builder.setProjectAttributes(new ProjectAttributes(null, "version_1", buildString));
     }
     return builder;
   }
index 2788ecd315a7ebfd63eb88c0f9083945f6470ace..cd49f88736983e8b64cb17110ce6c8995d545185 100644 (file)
@@ -28,6 +28,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Random;
 import java.util.function.Function;
 import javax.annotation.Nullable;
@@ -70,7 +71,7 @@ public class ComponentTreeBuilderTest {
   // both no project as "" or null should be supported
   private static final ProjectAttributes SOME_PROJECT_ATTRIBUTES = new ProjectAttributes(
     new Random().nextBoolean() ? null : randomAlphabetic(12),
-    randomAlphabetic(20));
+    randomAlphabetic(20), randomAlphabetic(21));
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
@@ -131,13 +132,14 @@ public class ComponentTreeBuilderTest {
   public void by_default_project_fields_are_loaded_from_report(@Nullable String projectVersion) {
     String nameInReport = "the name";
     String descriptionInReport = "the desc";
+    String buildString = randomAlphabetic(21);
     Component root = call(newBuilder()
       .setType(PROJECT)
       .setKey(projectInDb.getKey())
       .setRef(42)
       .setName(nameInReport)
       .setDescription(descriptionInReport)
-      .build(), NO_SCM_BASE_PATH, new ProjectAttributes(projectVersion, "6.5"));
+      .build(), NO_SCM_BASE_PATH, new ProjectAttributes(projectVersion, "6.5", buildString));
 
     assertThat(root.getUuid()).isEqualTo("generated_K1_uuid");
     assertThat(root.getDbKey()).isEqualTo("generated_K1");
@@ -153,6 +155,7 @@ public class ComponentTreeBuilderTest {
       assertThat(root.getProjectAttributes().getProjectVersion()).contains(projectVersion);
     }
     assertThat(root.getProjectAttributes().getCodePeriodVersion()).isEqualTo("6.5");
+    assertThat(root.getProjectAttributes().getBuildString()).isEqualTo(Optional.of(buildString));
     assertThatFileAttributesAreNotSet(root);
   }
 
index 2a48e802cf75861db5ca9af1b306c8a4a903efab..da34e9235d8a50bfefa7e1149fdeae2657e471cd 100644 (file)
@@ -70,7 +70,7 @@ public class ReportComponent implements Component {
     this.description = builder.description;
     this.uuid = builder.uuid;
     this.projectAttributes = Optional.ofNullable(builder.codePeriodVersion)
-      .map(t -> new ProjectAttributes(builder.projectVersion, t))
+      .map(t -> new ProjectAttributes(builder.projectVersion, t, builder.buildString))
       .orElse(null);
     this.reportAttributes = ReportAttributes.newBuilder(builder.ref)
       .build();
@@ -207,6 +207,7 @@ public class ReportComponent implements Component {
     private String shortName;
     private String codePeriodVersion;
     private String projectVersion;
+    private String buildString;
     private String description;
     private FileAttributes fileAttributes;
     private final List<Component> children = new ArrayList<>();
@@ -251,7 +252,7 @@ public class ReportComponent implements Component {
     }
 
     public Builder setCodePeriodVersion(String s) {
-      checkCodePeriodVersion(s);
+      checkArgument(type != Type.PROJECT ^ s != null, "CodePeriod version must and can only be set on Project");
       this.codePeriodVersion = s;
       return this;
     }
@@ -261,6 +262,11 @@ public class ReportComponent implements Component {
       return this;
     }
 
+    public Builder setBuildString(@Nullable String buildString) {
+      this.buildString = buildString;
+      return this;
+    }
+
     public Builder setFileAttributes(FileAttributes fileAttributes) {
       checkState(type == Type.FILE, "Only Component of type File can have File attributes");
       this.fileAttributes = fileAttributes;
@@ -281,13 +287,9 @@ public class ReportComponent implements Component {
     }
 
     public ReportComponent build() {
-      checkCodePeriodVersion(this.codePeriodVersion);
+      checkArgument(type != Type.PROJECT ^ this.codePeriodVersion != null, "CodePeriod version must and can only be set on Project");
+      checkArgument(type == Type.PROJECT || this.buildString == null, "BuildString can only be set on Project");
       return new ReportComponent(this);
     }
-
-    private void checkCodePeriodVersion(@Nullable String s) {
-      checkArgument(type != Type.PROJECT ^ s != null, "CodePeriod version must and can only be set on Project");
-    }
   }
-
 }
index 29d71d67d1f1b94fb50376f38c06502b95dd785e..1fa66c1a2856cd9a11a6f6a2f766035a637cae09 100644 (file)
@@ -24,6 +24,7 @@ import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Optional;
 import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
@@ -469,6 +470,20 @@ public class BuildComponentTreeStepTest {
     assertThat(treeRootHolder.getReportTreeRoot().getProjectAttributes().getProjectVersion()).contains(projectVersion);
   }
 
+  @Test
+  @UseDataProvider("oneParameterNullNonNullCombinations")
+  public void set_buildString(@Nullable String buildString) {
+    String projectVersion = randomAlphabetic(7);
+    String codePeriodVersion = randomAlphabetic(8);
+    setAnalysisMetadataHolder();
+    reportReader.setMetadata(createReportMetadata(projectVersion, codePeriodVersion, buildString));
+    reportReader.putComponent(component(ROOT_REF, PROJECT, REPORT_PROJECT_KEY));
+
+    underTest.execute(new TestComputationStepContext());
+
+    assertThat(treeRootHolder.getReportTreeRoot().getProjectAttributes().getBuildString()).isEqualTo(Optional.ofNullable(buildString));
+  }
+
   @DataProvider
   public static Object[][] oneParameterNullNonNullCombinations() {
     return new Object[][] {
@@ -608,11 +623,16 @@ public class BuildComponentTreeStepTest {
   }
 
   public static ScannerReport.Metadata createReportMetadata(@Nullable String projectVersion, @Nullable String scannerCodePeriodVersion) {
+    return createReportMetadata(projectVersion, scannerCodePeriodVersion, null);
+  }
+
+  public static ScannerReport.Metadata createReportMetadata(@Nullable String projectVersion, @Nullable String scannerCodePeriodVersion, @Nullable String buildString) {
     ScannerReport.Metadata.Builder builder = ScannerReport.Metadata.newBuilder()
       .setProjectKey(REPORT_PROJECT_KEY)
       .setRootComponentRef(ROOT_REF);
     ofNullable(scannerCodePeriodVersion).ifPresent(builder::setCodePeriodVersion);
     ofNullable(projectVersion).ifPresent(builder::setProjectVersion);
+    ofNullable(buildString).ifPresent(builder::setBuildString);
     return builder.build();
   }
 
index 23f7f75716a37775f427df33f4b1409262ec2195..22e6835fc61af091827444b87e7bde4c1e670e8e 100644 (file)
@@ -23,6 +23,8 @@ import com.tngtech.java.junit.dataprovider.DataProvider;
 import com.tngtech.java.junit.dataprovider.DataProviderRunner;
 import com.tngtech.java.junit.dataprovider.UseDataProvider;
 import java.util.List;
+import java.util.Optional;
+import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -100,7 +102,7 @@ public class ReportPersistAnalysisStepTest extends BaseStepTest {
 
   @Test
   @UseDataProvider("projectVersionOrNull")
-  public void persist_analysis(String projectVersion) {
+  public void persist_analysis(@Nullable String projectVersion) {
     OrganizationDto organizationDto = dbTester.organizations().insert();
     ComponentDto projectDto = ComponentTesting.newPrivateProjectDto(organizationDto, "ABCD").setDbKey(PROJECT_KEY).setName("Project");
     dbClient.componentDao().insert(dbTester.getSession(), projectDto);
@@ -114,11 +116,13 @@ public class ReportPersistAnalysisStepTest extends BaseStepTest {
 
     Component file = ReportComponent.builder(Component.Type.FILE, 3).setUuid("DEFG").setKey("MODULE_KEY:src/main/java/dir/Foo.java").build();
     Component directory = ReportComponent.builder(Component.Type.DIRECTORY, 2).setUuid("CDEF").setKey("MODULE_KEY:src/main/java/dir").addChildren(file).build();
+    String buildString = Optional.ofNullable(projectVersion).map(v -> randomAlphabetic(7)).orElse(null);
     Component project = ReportComponent.builder(Component.Type.PROJECT, 1)
       .setUuid("ABCD")
       .setKey(PROJECT_KEY)
       .setCodePeriodVersion("1.0")
       .setProjectVersion(projectVersion)
+      .setBuildString(buildString)
       .addChildren(directory)
       .build();
     treeRootHolder.setRoot(project);
@@ -136,6 +140,7 @@ public class ReportPersistAnalysisStepTest extends BaseStepTest {
     assertThat(projectSnapshot.getComponentUuid()).isEqualTo(project.getUuid());
     assertThat(projectSnapshot.getCodePeriodVersion()).isEqualTo("1.0");
     assertThat(projectSnapshot.getProjectVersion()).isEqualTo(projectVersion);
+    assertThat(projectSnapshot.getBuildString()).isEqualTo(buildString);
     assertThat(projectSnapshot.getLast()).isFalse();
     assertThat(projectSnapshot.getStatus()).isEqualTo("U");
     assertThat(projectSnapshot.getCreatedAt()).isEqualTo(analysisDate);
index 34decebab6b176e9e6c3f028fb94752dad405e04..80c4b377e4db8ecba68773c86512c22fd35c8adb 100644 (file)
@@ -143,6 +143,7 @@ CREATE TABLE "SNAPSHOTS" (
   "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
   "VERSION" VARCHAR(500),
   "PROJECT_VERSION" VARCHAR(100),
+  "BUILD_STRING" VARCHAR(100),
   "PERIOD1_MODE" VARCHAR(100),
   "PERIOD1_PARAM" VARCHAR(100),
   "PERIOD1_DATE" BIGINT,
index d96035e0bdfba8e4446016d85d3d8a14c7afc433..d6c8766fc2e616c177497f45867c17cd9e52857c 100644 (file)
@@ -43,6 +43,7 @@ public final class SnapshotDto {
   private Boolean last;
   private String codePeriodVersion;
   private String projectVersion;
+  private String buildString;
   private String periodMode;
   private String periodParam;
   private Long periodDate;
@@ -147,6 +148,16 @@ public final class SnapshotDto {
     this.projectVersion = projectVersion;
   }
 
+  @CheckForNull
+  public String getBuildString() {
+    return buildString;
+  }
+
+  public SnapshotDto setBuildString(@Nullable String buildString) {
+    this.buildString = buildString;
+    return this;
+  }
+
   public SnapshotDto setPeriodMode(@Nullable String p) {
     periodMode = p;
     return this;
index 9d2e6043c792afb8c816b6b814914ee3bdd66a3c..15fd82615495757544a570ea730130595ca95737 100644 (file)
@@ -12,6 +12,7 @@
     s.islast as last,
     s.version as rawCodePeriodVersion,
     s.project_version as rawProjectVersion,
+    s.build_string as buildString,
     s.period1_mode as periodMode,
     s.period1_param as periodParam,
     s.period1_date as periodDate
       islast,
       version,
       project_version,
+      build_string,
       period1_mode,
       period1_param,
       period1_date
       #{last, jdbcType=BOOLEAN},
       #{codePeriodVersion, jdbcType=VARCHAR},
       #{projectVersion, jdbcType=VARCHAR},
+      #{buildString, jdbcType=VARCHAR},
       #{periodMode, jdbcType=VARCHAR},
       #{periodParam, jdbcType=VARCHAR},
       #{periodDate, jdbcType=BIGINT}
index e7651e44899bd26337c60066dfc23a41296faed3..e9e512f02d24da81928ff6c5cf2bfd3229ad1698 100644 (file)
@@ -33,6 +33,7 @@ Note that measures, events and reviews are not deleted.
              build_date="1228222680000"
              version="[null]"
              project_version="[null]"
+             build_string="[null]"
   />
   <analysis_properties uuid="u1"
                        snapshot_uuid="u1"
index 3d926d2b8eda0e09e4dbdd9ba2c3139b2a3b1d97..c70adbbf8369f89753463ef0196698b2d3dfcc25 100644 (file)
@@ -51,6 +51,7 @@ Snapshot 2 has been deleted
              build_date="1228222680000"
              version="[null]"
              project_version="[null]"
+             build_string="[null]"
   />
 
   <!-- snapshot with status "processed" and flagged as "last" -> do not purge and do not delete -->
index bc8a1e2382eb6740910760914f75e1d91f67b629..16a0bab013ec265e35b4ce09c819b02349f5accb 100644 (file)
@@ -26,6 +26,7 @@
              build_date="1228222680000"
              version="[null]"
              project_version="[null]"
+             build_string="[null]"
   />
 
   <!-- delete only resource 1 -->
index 259be92616c6f34a285c8317d81590140370e67b..39fe34d21c789c4d89e04b9b6601a48ed700df4e 100644 (file)
              build_date="1228222680000"
              version="[null]"
              project_version="[null]"
+             build_string="[null]"
   />
 
   <project_measures id="1"
index d58479413b82538d9b4c4f00961e756f3b24488a..7f10558d0a9ef055bec153b52a0c2970d842494d 100644 (file)
@@ -67,6 +67,7 @@
              build_date="1228222680000"
              version="[null]"
              project_version="[null]"
+             build_string="[null]"
   />
 
 
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshot.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshot.java
new file mode 100644 (file)
index 0000000..2390465
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.v77;
+
+import java.sql.SQLException;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
+import org.sonar.server.platform.db.migration.sql.AddColumnsBuilder;
+import org.sonar.server.platform.db.migration.step.DdlChange;
+
+import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVarcharColumnDefBuilder;
+
+@SupportsBlueGreen
+public class AddBuildStringToSnapshot extends DdlChange {
+  private static final String TABLE_NAME = "snapshots";
+  private static final VarcharColumnDef COLUMN = newVarcharColumnDefBuilder()
+    .setColumnName("build_string")
+    .setIsNullable(true)
+    .setLimit(100)
+    .build();
+
+  public AddBuildStringToSnapshot(Database db) {
+    super(db);
+  }
+
+  @Override
+  public void execute(Context context) throws SQLException {
+    context.execute(new AddColumnsBuilder(getDialect(), TABLE_NAME)
+      .addColumn(COLUMN)
+      .build());
+  }
+}
index e4d052bb8d1b433371956e3bd5f815edf45fbc82..c12afef8e3b3f73ef3445e6252ba52b2c7c43f4c 100644 (file)
@@ -38,7 +38,7 @@ public class DbVersion77 implements DbVersion {
       .add(2608, "Delete favorites on not supported components", DeleteFavouritesOnNotSupportedComponentQualifiers.class)
       .add(2609, "Delete exceeding favorites when there are more than 100 for a user", DeleteFavoritesExceedingOneHundred.class)
       .add(2610, "Truncate ES_QUEUE table content", TruncateEsQueue.class)
-
+      .add(2611, "Add SNAPSHOTS.BUILD_STRING", AddBuildStringToSnapshot.class)
     ;
   }
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshotTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshotTest.java
new file mode 100644 (file)
index 0000000..a9fda0f
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2019 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.v77;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.db.CoreDbTester;
+
+import static java.sql.Types.VARCHAR;
+
+public class AddBuildStringToSnapshotTest {
+
+  private static final String TABLE = "snapshots";
+
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+  @Rule
+  public final CoreDbTester db = CoreDbTester.createForSchema(AddBuildStringToSnapshotTest.class, "snapshots.sql");
+
+  private AddBuildStringToSnapshot underTest = new AddBuildStringToSnapshot(db.database());
+
+  @Test
+  public void creates_table_on_empty_db() throws SQLException {
+    underTest.execute();
+
+    db.assertColumnDefinition(TABLE, "project_version", VARCHAR, 100, true);
+  }
+
+  @Test
+  public void migration_is_not_reentrant() throws SQLException {
+    underTest.execute();
+
+    expectedException.expect(IllegalStateException.class);
+
+    underTest.execute();
+  }
+
+}
index 001eef0e5214f0c815ecd86066363b6e6355d883..802d22d59a398a9dac56b9f91d75b543786e421d 100644 (file)
@@ -36,7 +36,7 @@ public class DbVersion77Test {
 
   @Test
   public void verify_migration_count() {
-    verifyMigrationCount(underTest, 11);
+    verifyMigrationCount(underTest, 12);
   }
 
 }
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshotTest/snapshots.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v77/AddBuildStringToSnapshotTest/snapshots.sql
new file mode 100644 (file)
index 0000000..30a335b
--- /dev/null
@@ -0,0 +1,29 @@
+CREATE TABLE "SNAPSHOTS" (
+  "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+  "UUID" VARCHAR(50) NOT NULL,
+  "CREATED_AT" BIGINT,
+  "BUILD_DATE" BIGINT,
+  "COMPONENT_UUID" VARCHAR(50) NOT NULL,
+  "STATUS" VARCHAR(4) NOT NULL DEFAULT 'U',
+  "PURGE_STATUS" INTEGER,
+  "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE,
+  "VERSION" VARCHAR(500),
+  "PROJECT_VERSION" VARCHAR(100),
+  "PERIOD1_MODE" VARCHAR(100),
+  "PERIOD1_PARAM" VARCHAR(100),
+  "PERIOD1_DATE" BIGINT,
+  "PERIOD2_MODE" VARCHAR(100),
+  "PERIOD2_PARAM" VARCHAR(100),
+  "PERIOD2_DATE" BIGINT,
+  "PERIOD3_MODE" VARCHAR(100),
+  "PERIOD3_PARAM" VARCHAR(100),
+  "PERIOD3_DATE" BIGINT,
+  "PERIOD4_MODE" VARCHAR(100),
+  "PERIOD4_PARAM" VARCHAR(100),
+  "PERIOD4_DATE" BIGINT,
+  "PERIOD5_MODE" VARCHAR(100),
+  "PERIOD5_PARAM" VARCHAR(100),
+  "PERIOD5_DATE" BIGINT
+);
+CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS" ("COMPONENT_UUID");
+CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS" ("UUID");