diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2019-08-21 06:08:31 -0500 |
---|---|---|
committer | SonarTech <sonartech@sonarsource.com> | 2019-09-24 20:21:14 +0200 |
commit | d650e5eeb4098ff100fb9382ddb8ea51588b58f9 (patch) | |
tree | 8c0dc1b55dd81485c3baaf02da6f4a52a5ae2ebc /server/sonar-db-migration | |
parent | d170d4e4812844d37a7ec0355ba968bc9ef55545 (diff) | |
download | sonarqube-d650e5eeb4098ff100fb9382ddb8ea51588b58f9.tar.gz sonarqube-d650e5eeb4098ff100fb9382ddb8ea51588b58f9.zip |
Feature/dm/migrate new code period (#2017)
* SONAR-12396 List new code periods for all branches with effective current values
* SONAR-12347 Migrate old definitions of leak period
Diffstat (limited to 'server/sonar-db-migration')
3 files changed, 478 insertions, 38 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTable.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTable.java index 48a659808b6..c2fbb0ffcad 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTable.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTable.java @@ -20,14 +20,30 @@ package org.sonar.server.platform.db.migration.version.v80; import java.sql.SQLException; +import java.time.LocalDate; +import java.time.ZoneId; +import java.time.format.DateTimeParseException; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import javax.annotation.Nullable; import org.sonar.api.utils.System2; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.sonar.core.util.UuidFactory; import org.sonar.db.Database; import org.sonar.server.platform.db.migration.step.DataChange; import org.sonar.server.platform.db.migration.step.Upsert; public class PopulateNewCodePeriodTable extends DataChange { + private static final Logger LOG = Loggers.get(PopulateNewCodePeriodTable.class); + + private static final String TYPE_PREVIOUS_VERSION = "PREVIOUS_VERSION"; + private static final String TYPE_NUMBER_OF_DAYS = "NUMBER_OF_DAYS"; + private static final String TYPE_SPECIFIC_ANALYSIS = "SPECIFIC_ANALYSIS"; + + private static final String LEAK_PERIOD_PROP_KEY = "sonar.leak.period"; private final UuidFactory uuidFactory; private final System2 system2; @@ -40,41 +56,132 @@ public class PopulateNewCodePeriodTable extends DataChange { @Override protected void execute(Context context) throws SQLException { - List<ProjectBranchCodePeriod> projectBranchCodePeriods = context.prepareSelect( - "select pb.uuid, pb.project_uuid, pb.manual_baseline_analysis_uuid from project_branches pb where pb.manual_baseline_analysis_uuid is not null") + List<String> branchUuidsAlreadyMigrated = populateFromManualBaselines(context); + populateFromSettings(context, branchUuidsAlreadyMigrated); + } + + private List<String> populateFromManualBaselines(Context context) throws SQLException { + List<ProjectBranchManualBaselineDto> projectBranchManualBaselines = context.prepareSelect( + "SELECT pb.uuid, pb.project_uuid, pb.manual_baseline_analysis_uuid FROM project_branches pb WHERE pb.manual_baseline_analysis_uuid IS NOT NULL") .list(row -> { String branchUuid = row.getString(1); String projectUuid = row.getString(2); String manualBaselineAnalysisUuid = row.getString(3); - return new ProjectBranchCodePeriod(branchUuid, projectUuid, manualBaselineAnalysisUuid); + return new ProjectBranchManualBaselineDto(branchUuid, projectUuid, manualBaselineAnalysisUuid); + }); + + if (!projectBranchManualBaselines.isEmpty()) { + populateWithManualBaselines(context, projectBranchManualBaselines); + } + + return projectBranchManualBaselines.stream() + .map(pb -> pb.branchUuid) + .collect(Collectors.toList()); + } + + private void populateFromSettings(Context context, List<String> branchUuidsAlreadyMigrated) throws SQLException { + // migrate global setting + String globalSetting = context + .prepareSelect("SELECT props.text_value FROM properties props WHERE props.prop_key = '" + LEAK_PERIOD_PROP_KEY + "' AND props.resource_id IS NULL") + .get(r -> r.getString(1)); + if (globalSetting != null) { + populateGlobalSetting(context, globalSetting); + } + + List<BranchLeakPeriodPropertyDto> projectLeakPeriodProperties = new ArrayList<>(); + context.prepareSelect( + "SELECT projs.uuid, projs.main_branch_project_uuid, props.text_value " + + "FROM properties props INNER JOIN projects projs ON props.resource_id = projs.id " + + "WHERE props.prop_key = '" + LEAK_PERIOD_PROP_KEY + "' AND props.resource_id IS NOT NULL ") + .scroll(row -> { + String branchUuid = row.getString(1); + if (branchUuidsAlreadyMigrated.contains(branchUuid)) { + return; + } + String mainBranchUuid = row.getString(2); + String value = row.getString(3); + if (mainBranchUuid == null) { + mainBranchUuid = branchUuid; + } + projectLeakPeriodProperties.add(new BranchLeakPeriodPropertyDto(branchUuid, mainBranchUuid, value)); }); - if (!projectBranchCodePeriods.isEmpty()) { - populateProjectBranchCodePeriods(context, projectBranchCodePeriods); + populateWithSettings(context, projectLeakPeriodProperties); + } + + private void populateGlobalSetting(Context context, String value) { + Optional<TypeValuePair> typeValue = tryParse(context, null, value); + typeValue.ifPresent(tp -> { + try (Upsert upsertQuery = prepareUpsertNewCodePeriodQuery(context)) { + long currentTime = system2.now(); + insert(upsertQuery, null, null, tp.type, tp.value, currentTime); + upsertQuery + .execute() + .commit(); + } catch (SQLException e) { + LOG.warn("Failed to migrate the global property for the new code period", e); + } + }); + } + + private void populateWithSettings(Context context, List<BranchLeakPeriodPropertyDto> projectLeakPeriodProperties) throws SQLException { + try (Upsert upsertQuery = prepareUpsertNewCodePeriodQuery(context)) { + long currentTime = system2.now(); + boolean commit = false; + + for (BranchLeakPeriodPropertyDto branchLeakPeriodProperty : projectLeakPeriodProperties) { + Optional<TypeValuePair> typeValueOpt = tryParse(context, branchLeakPeriodProperty.branchUuid, branchLeakPeriodProperty.value); + if (!typeValueOpt.isPresent()) { + continue; + } + + TypeValuePair typeValue = typeValueOpt.get(); + + String branchUuid = null; + if (!branchLeakPeriodProperty.isMainBranch() || TYPE_SPECIFIC_ANALYSIS.equals(typeValue.type)) { + branchUuid = branchLeakPeriodProperty.branchUuid; + } + + insert(upsertQuery, branchLeakPeriodProperty.mainBranchUuid, branchUuid, typeValue.type, typeValue.value, currentTime); + commit = true; + } + + if (commit) { + upsertQuery + .execute() + .commit(); + } } } - private void populateProjectBranchCodePeriods(Context context, List<ProjectBranchCodePeriod> projectBranchCodePeriods) throws SQLException { - Upsert insertQuery = prepareInsertProjectQualityGateQuery(context); - for (ProjectBranchCodePeriod projectBranchCodePeriod : projectBranchCodePeriods) { - long currenTime = system2.now(); - insertQuery - .setString(1, uuidFactory.create()) - .setString(2, projectBranchCodePeriod.projectUuid) - .setString(3, projectBranchCodePeriod.branchUuid) - .setString(4, "SPECIFIC_ANALYSIS") - .setString(5, projectBranchCodePeriod.manualBaselineAnalysisUuid) - .setLong(6, currenTime) - .setLong(7, currenTime) - .addBatch(); + private void populateWithManualBaselines(Context context, List<ProjectBranchManualBaselineDto> projectBranchManualBaselines) throws SQLException { + try (Upsert upsertQuery = prepareUpsertNewCodePeriodQuery(context)) { + long currentTime = system2.now(); + + for (ProjectBranchManualBaselineDto projectBranchManualBaseline : projectBranchManualBaselines) { + insert(upsertQuery, projectBranchManualBaseline.projectUuid, projectBranchManualBaseline.branchUuid, TYPE_SPECIFIC_ANALYSIS, + projectBranchManualBaseline.manualBaselineAnalysisUuid, currentTime); + } + upsertQuery + .execute() + .commit(); } - insertQuery - .execute() - .commit(); } - private static Upsert prepareInsertProjectQualityGateQuery(Context context) throws SQLException { - return context.prepareUpsert("insert into new_code_periods(" + + private void insert(Upsert upsert, @Nullable String projectUuid, @Nullable String branchUuid, String type, @Nullable String value, long currentTime) throws SQLException { + upsert + .setString(1, uuidFactory.create()) + .setString(2, projectUuid) + .setString(3, branchUuid) + .setString(4, type) + .setString(5, value) + .setLong(6, currentTime) + .setLong(7, currentTime) + .addBatch(); + } + + private static Upsert prepareUpsertNewCodePeriodQuery(Context context) throws SQLException { + return context.prepareUpsert("INSERT INTO new_code_periods(" + "uuid, " + "project_uuid," + "branch_uuid," + @@ -85,16 +192,102 @@ public class PopulateNewCodePeriodTable extends DataChange { ") VALUES (?, ?, ?, ?, ?, ?, ?)"); } - private static class ProjectBranchCodePeriod { + private static Optional<TypeValuePair> tryParse(Context context, @Nullable String branchUuid, String value) { + try { + if (value.equals("previous_version")) { + return Optional.of(new TypeValuePair(TYPE_PREVIOUS_VERSION, null)); + } + + try { + Integer.parseInt(value); + return Optional.of(new TypeValuePair(TYPE_NUMBER_OF_DAYS, value)); + } catch (NumberFormatException e) { + // ignore + } + + if (branchUuid == null) { + return Optional.empty(); + } + + try { + LocalDate localDate = LocalDate.parse(value); + Optional<String> snapshot = findFirstSnapshot(context, branchUuid, localDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()); + return snapshot.map(uuid -> new TypeValuePair(TYPE_SPECIFIC_ANALYSIS, uuid)); + } catch (DateTimeParseException e) { + // ignore + } + + List<EventDto> versions = getVersionsByMostRecentFirst(context, branchUuid); + Optional<EventDto> versionMatch = versions.stream().filter(v -> v.version.equals(value)).findFirst(); + return versionMatch.map(e -> new TypeValuePair(TYPE_SPECIFIC_ANALYSIS, e.analysisUuid)); + } catch (SQLException e) { + LOG.warn("Failed to migrate a property for the new code period", e); + return Optional.empty(); + } + } + + private static List<EventDto> getVersionsByMostRecentFirst(Context context, String branchUuid) throws SQLException { + // TODO in LoadPeriodsStep we do a join with snapshots and see if the analysis is still unprocessed. Do we need to do it here? + return context.prepareSelect("SELECT name, analysis_uuid FROM events " + + "WHERE component_uuid = '" + branchUuid + "' AND category = 'Version' " + + "ORDER BY created_at DESC") + .list(r -> new EventDto(r.getString(1), r.getString(2))); + } + + private static Optional<String> findFirstSnapshot(Context context, String branchUuid, long date) throws SQLException { + String analysisUuid = context.prepareSelect("SELECT uuid FROM snapshots " + + "WHERE component_uuid = '" + branchUuid + "' AND created_at > " + date + " AND status = 'P' " + + "ORDER BY created_at ASC") + .get(r -> r.getString(1)); + return Optional.ofNullable(analysisUuid); + } + + private static class TypeValuePair { + private final String type; + @Nullable + private final String value; + + private TypeValuePair(String type, @Nullable String value) { + this.type = type; + this.value = value; + } + } + + private static class EventDto { + private final String version; + private final String analysisUuid; + + private EventDto(String version, String analysisUuid) { + this.version = version; + this.analysisUuid = analysisUuid; + } + } + + private static class ProjectBranchManualBaselineDto { private final String branchUuid; private final String projectUuid; private final String manualBaselineAnalysisUuid; - ProjectBranchCodePeriod(String branchUuid, String projectUuid, String manualBaselineAnalysisUuid) { + ProjectBranchManualBaselineDto(String branchUuid, String projectUuid, String manualBaselineAnalysisUuid) { this.branchUuid = branchUuid; this.projectUuid = projectUuid; this.manualBaselineAnalysisUuid = manualBaselineAnalysisUuid; } } + private static class BranchLeakPeriodPropertyDto { + private final String branchUuid; + private final String mainBranchUuid; + private final String value; + + BranchLeakPeriodPropertyDto(String branchUuid, String mainBranchUuid, String value) { + this.branchUuid = branchUuid; + this.mainBranchUuid = mainBranchUuid; + this.value = value; + } + + private boolean isMainBranch() { + return mainBranchUuid.equals(branchUuid); + } + } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest.java index 913de150842..fe673114962 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest.java @@ -20,14 +20,23 @@ package org.sonar.server.platform.db.migration.version.v80; import java.sql.SQLException; -import org.junit.Assert; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.Map; +import java.util.Optional; +import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; import org.sonar.core.util.UuidFactoryImpl; import org.sonar.db.CoreDbTester; +import static java.lang.String.valueOf; +import static org.assertj.core.api.Assertions.assertThat; + public class PopulateNewCodePeriodTableTest { private static final String NEW_CODE_PERIODS_TABLE_NAME = "new_code_periods"; private static final String PROJECT_BRANCHES_TABLE_NAME = "project_branches"; @@ -35,7 +44,6 @@ public class PopulateNewCodePeriodTableTest { @Rule public CoreDbTester dbTester = CoreDbTester.createForSchema(PopulateNewCodePeriodTableTest.class, "schema.sql"); - @Rule public ExpectedException expectedException = ExpectedException.none(); @@ -43,31 +51,211 @@ public class PopulateNewCodePeriodTableTest { @Test public void copy_manual_baseline_analysis_to_new_code_period_table() throws SQLException { - for (long i = 1; i <= NUMBER_OF_PROJECT_BRANCHES_TO_INSERT; i++) { - insertProjectBranch(i); + for (long i = 0; i < NUMBER_OF_PROJECT_BRANCHES_TO_INSERT; i++) { + insertMainBranch(i, true); } underTest.execute(); + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(10); - int propertiesCount = dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME); - Assert.assertEquals(10, propertiesCount); + for (int i = 0; i < NUMBER_OF_PROJECT_BRANCHES_TO_INSERT; i++) { + assertNewCodePeriod(i, "pb-uuid-" + i, "pb-uuid-" + i, "SPECIFIC_ANALYSIS", "mba-uuid" + i); + } //should not fail if executed twice underTest.execute(); } - private void insertProjectBranch(long counter) { + @Test + public void do_nothing_if_cant_find_matching_analysis() throws SQLException { + insertMainBranch(0, false); + insertMainBranch(1, false); + + insertProperty(0, "2.0"); + insertProperty(0, "2019-04-05"); + + underTest.execute(); + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(0); + } + + @Test + public void do_nothing_if_cant_migrate_global_property() throws SQLException { + insertProperty(null, "2.0"); + + underTest.execute(); + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(0); + } + + @Test + public void migrate_project_property_set_to_previous_version() throws SQLException { + insertMainBranch(0, true); + insertMainBranch(1, false); + // no property defined for it + insertMainBranch(2, false); + + // doesn't get copied since there is a manual baseline taking precedence + insertProperty(0, "20"); + insertProperty(1, "previous_version"); + // doesn't exist + insertProperty(3, "previous_version"); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(2); + assertNewCodePeriod(0, "pb-uuid-" + 0, "pb-uuid-" + 0, "SPECIFIC_ANALYSIS", "mba-uuid" + 0); + assertNewCodePeriod(1, "pb-uuid-" + 1, null, "PREVIOUS_VERSION", null); + } + + @Test + public void migrate_project_property_set_to_number_of_days() throws SQLException { + insertMainBranch(0, false); + insertBranch(0, 1, false); + insertProperty(1, "20"); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(1); + assertNewCodePeriod(0, "pb-uuid-" + 0, "pb-uuid-" + 1, "NUMBER_OF_DAYS", "20"); + } + + @Test + public void migrate_branch_property_set_to_number_of_days() throws SQLException { + insertMainBranch(0, false); + insertProperty(0, "20"); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(1); + assertNewCodePeriod(0, "pb-uuid-" + 0, null, "NUMBER_OF_DAYS", "20"); + } + + @Test + public void migrate_global_property_set_to_number_of_days() throws SQLException { + insertProperty(null, "20"); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(1); + assertNewCodePeriod(0, null, null, "NUMBER_OF_DAYS", "20"); + } + + + @Test + public void migrate_project_property_set_to_version() throws SQLException { + insertMainBranch(0, false); + insertProperty(0, "2.0"); + + insertVersionEvent(0, 10L, "1.0"); + insertVersionEvent(0, 20L, "2.0"); + insertVersionEvent(0, 30L, "3.0"); + insertVersionEvent(0, 40L, "2.0"); + insertVersionEvent(0, 50L, "3.0"); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(1); + // we don't support specific analysis for projects, so we set it for the branch + assertNewCodePeriod(0, "pb-uuid-" + 0, "pb-uuid-" + 0, "SPECIFIC_ANALYSIS", "analysis-40"); + } + + @Test + public void migrate_project_property_set_to_date() throws SQLException { + insertMainBranch(0, false); + insertProperty(0, "2019-04-05"); + + long reference = LocalDate.parse("2019-04-05").atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli(); + insertSnapshot(100, 0, reference - 100); + insertSnapshot(200, 0, reference + 100); + insertSnapshot(300, 0, reference + 200); + + underTest.execute(); + + assertThat(dbTester.countRowsOfTable(NEW_CODE_PERIODS_TABLE_NAME)).isEqualTo(1); + // we don't support specific analysis for projects, so we set it for the branch + assertNewCodePeriod(0, "pb-uuid-" + 0, "pb-uuid-" + 0, "SPECIFIC_ANALYSIS", "snapshot-200"); + } + + private void assertNewCodePeriod(int row, @Nullable String projectUuid, @Nullable String branchUuid, String type, @Nullable String value) { + Optional<Map<String, Object>> r = dbTester.select("SELECT PROJECT_UUID, BRANCH_UUID, TYPE, VALUE FROM " + NEW_CODE_PERIODS_TABLE_NAME) + .stream() + .skip(row) + .findFirst(); + + assertThat(r).isPresent(); + + assertThat(r.get().get("PROJECT_UUID")).isEqualTo(projectUuid); + assertThat(r.get().get("BRANCH_UUID")).isEqualTo(branchUuid); + assertThat(r.get().get("TYPE")).isEqualTo(type); + assertThat(r.get().get("VALUE")).isEqualTo(value); + } + + private void insertBranch(long mainBranchUid, long uid, boolean withBaseLine) { + String manualBaseline = withBaseLine ? "mba-uuid" + uid : null; + + String mainBranchProjectUuid = mainBranchUid == uid ? null : "pb-uuid-" + mainBranchUid; + insertComponent(uid, "pb-uuid-" + uid, mainBranchProjectUuid); + dbTester.executeInsert( PROJECT_BRANCHES_TABLE_NAME, - "UUID", "pb-uuid-" + counter, - "PROJECT_UUID", "pb-uuid-" + counter, - "KEE", "pb-key-" + counter, + "UUID", "pb-uuid-" + uid, + "PROJECT_UUID", "pb-uuid-" + mainBranchUid, + "KEE", "pb-key-" + uid, "KEY_TYPE", "TSR", "BRANCH_TYPE", "LONG", - "MERGE_BRANCH_UUID", "mb-uuid-" + counter, - "MANUAL_BASELINE_ANALYSIS_UUID", "mba-uuid" + counter, + "MERGE_BRANCH_UUID", "mb-uuid-" + mainBranchUid, + "MANUAL_BASELINE_ANALYSIS_UUID", manualBaseline, "CREATED_AT", System2.INSTANCE.now(), "UPDATED_AT", System2.INSTANCE.now() ); } + + private void insertSnapshot(int uid, int branchUid, long creationDate) { + dbTester.executeInsert( + "SNAPSHOTS", + "UUID", "snapshot-" + uid, + "COMPONENT_UUID", "pb-uuid-" + branchUid, + "STATUS", "P", + "CREATED_AT", creationDate + ); + } + + private void insertProperty(@Nullable Integer uid, String value) { + dbTester.executeInsert( + "PROPERTIES", + "PROP_KEY", "sonar.leak.period", + "RESOURCE_ID", uid, + "USER_ID", null, + "IS_EMPTY", false, + "TEXT_VALUE", value, + "CLOB_VALUE", null, + "CREATED_AT", System2.INSTANCE.now() + ); + } + + private void insertComponent(long id, String uuid, @Nullable String mainBranchProjectUuid) { + dbTester.executeInsert( + "projects", + "ID", valueOf(id), + "UUID", uuid, + "ROOT_UUID", uuid, + "PROJECT_UUID", uuid, + "MAIN_BRANCH_PROJECT_UUID", mainBranchProjectUuid, + "SCOPE", Scopes.PROJECT, + "QUALIFIER", "TRK", + "NAME", "name-" + id); + } + + private void insertVersionEvent(long id, long createdAt, String version) { + dbTester.executeInsert( + "events", + "ANALYSIS_UUID", "analysis-" + createdAt, + "NAME", version, + "COMPONENT_UUID", "pb-uuid-" + id, + "CATEGORY", "Version", + "CREATED_AT", createdAt); + } + + private void insertMainBranch(long uid, boolean withBaseLine) { + insertBranch(uid, uid, withBaseLine); + } } diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest/schema.sql index 799247fe6d9..d0f89a687c9 100644 --- a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest/schema.sql +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v80/PopulateNewCodePeriodTableTest/schema.sql @@ -19,9 +19,68 @@ CREATE TABLE "NEW_CODE_PERIODS" ( "PROJECT_UUID" VARCHAR(40), "BRANCH_UUID" VARCHAR(40), "TYPE" VARCHAR(30) NOT NULL, - "VALUE" VARCHAR(40) NOT NULL, + "VALUE" VARCHAR(40), "UPDATED_AT" BIGINT NOT NULL, "CREATED_AT" BIGINT NOT NULL, CONSTRAINT "PK_NEW_CODE_PERIOD" PRIMARY KEY ("UUID") ); + +CREATE TABLE "PROPERTIES" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "PROP_KEY" VARCHAR(512) NOT NULL, + "RESOURCE_ID" INTEGER, + "USER_ID" INTEGER, + "IS_EMPTY" BOOLEAN NOT NULL, + "TEXT_VALUE" VARCHAR(4000), + "CLOB_VALUE" CLOB, + "CREATED_AT" BIGINT +); +CREATE INDEX "PROPERTIES_KEY" ON "PROPERTIES" ("PROP_KEY"); + +CREATE TABLE "PROJECTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "KEE" VARCHAR(400), + "UUID" VARCHAR(50) NOT NULL, + "ROOT_UUID" VARCHAR(50), + "PROJECT_UUID" VARCHAR(50) NOT NULL, + "MODULE_UUID" VARCHAR(50), + "MODULE_UUID_PATH" VARCHAR(1500), + "MAIN_BRANCH_PROJECT_UUID" VARCHAR(50), + "NAME" VARCHAR(2000), + "TAGS" VARCHAR(500), + "ENABLED" BOOLEAN NOT NULL DEFAULT TRUE, + "SCOPE" VARCHAR(3), + "QUALIFIER" VARCHAR(10) +); +CREATE UNIQUE INDEX "PROJECTS_KEE" ON "PROJECTS" ("KEE"); +CREATE INDEX "PROJECTS_ROOT_UUID" ON "PROJECTS" ("ROOT_UUID"); +CREATE UNIQUE INDEX "PROJECTS_UUID" ON "PROJECTS" ("UUID"); +CREATE INDEX "PROJECTS_PROJECT_UUID" ON "PROJECTS" ("PROJECT_UUID"); +CREATE INDEX "PROJECTS_MODULE_UUID" ON "PROJECTS" ("MODULE_UUID"); +CREATE INDEX "PROJECTS_QUALIFIER" ON "PROJECTS" ("QUALIFIER"); + +CREATE TABLE "EVENTS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "NAME" VARCHAR(400), + "ANALYSIS_UUID" VARCHAR(50) NOT NULL, + "COMPONENT_UUID" VARCHAR(50) NOT NULL, + "CATEGORY" VARCHAR(50), + "CREATED_AT" BIGINT NOT NULL, + "DESCRIPTION" VARCHAR(4000), + "EVENT_DATA" VARCHAR(4000) +); +CREATE INDEX "EVENTS_ANALYSIS" ON "EVENTS" ("ANALYSIS_UUID"); +CREATE INDEX "EVENTS_COMPONENT_UUID" ON "EVENTS" ("COMPONENT_UUID"); + +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', + "ISLAST" BOOLEAN NOT NULL DEFAULT FALSE +); +CREATE INDEX "SNAPSHOT_COMPONENT" ON "SNAPSHOTS" ("COMPONENT_UUID"); +CREATE UNIQUE INDEX "ANALYSES_UUID" ON "SNAPSHOTS" ("UUID"); |