From: Duarte Meneses Date: Thu, 20 Aug 2020 15:08:59 +0000 (-0500) Subject: SONAR-13785 Complete migration of file sources with a DB migration X-Git-Tag: 8.5.0.37579~126 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=99be1088611bc7f39c67c3b88456a08a46216f4d;p=sonarqube.git SONAR-13785 Complete migration of file sources with a DB migration --- diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java index cfc3da144b5..7cd9fc307c3 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/container/ProjectAnalysisTaskContainerPopulator.java @@ -38,7 +38,6 @@ import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids import org.sonar.ce.task.projectanalysis.component.ReportModulesPath; import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderImpl; -import org.sonar.ce.task.projectanalysis.dbmigration.DbMigrationModule; import org.sonar.ce.task.projectanalysis.duplication.CrossProjectDuplicationStatusHolderImpl; import org.sonar.ce.task.projectanalysis.duplication.DuplicationMeasures; import org.sonar.ce.task.projectanalysis.duplication.DuplicationRepositoryImpl; @@ -182,7 +181,6 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop // File System new ComputationTempFolderProvider(), - DbMigrationModule.class, ReportModulesPath.class, MetricModule.class, diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/DbMigrationModule.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/DbMigrationModule.java deleted file mode 100644 index 07dc0537f22..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/DbMigrationModule.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import org.sonar.core.platform.Module; - -public class DbMigrationModule extends Module { - @Override - protected void configureModule() { - add(ProjectAnalysisDataChangesImpl.class); - ProjectAnalysisDataChangesImpl.getDataChangeClasses().forEach(this::add); - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java deleted file mode 100644 index ec6472084dd..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCount.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import com.google.common.collect.Iterables; -import java.sql.SQLException; -import org.sonar.ce.task.CeTask; -import org.sonar.db.Database; -import org.sonar.db.source.FileSourceDto; -import org.sonar.server.platform.db.migration.step.DataChange; -import org.sonar.server.platform.db.migration.step.MassUpdate; -import org.sonar.server.platform.db.migration.step.Select; -import org.sonar.server.platform.db.migration.step.SqlStatement; - -import static org.sonar.db.source.FileSourceDto.LINE_COUNT_NOT_POPULATED; - -public class PopulateFileSourceLineCount extends DataChange implements ProjectAnalysisDataChange { - private final CeTask ceTask; - - public PopulateFileSourceLineCount(Database database, CeTask ceTask) { - super(database); - this.ceTask = ceTask; - } - - @Override - protected void execute(Context context) throws SQLException { - String componentUuid = ceTask.getComponent().get().getUuid(); - Long unInitializedFileSources = context.prepareSelect("select count(1) from file_sources where line_count = ? and project_uuid = ?") - .setInt(1, LINE_COUNT_NOT_POPULATED) - .setString(2, componentUuid) - .get(row -> row.getLong(1)); - - if (unInitializedFileSources != null && unInitializedFileSources > 0) { - MassUpdate massUpdate = context.prepareMassUpdate(); - massUpdate.select("select uuid,line_hashes from file_sources where line_count = ? and project_uuid = ?") - .setInt(1, LINE_COUNT_NOT_POPULATED) - .setString(2, componentUuid); - massUpdate.update("update file_sources set line_count = ? where uuid = ?"); - massUpdate.rowPluralName("line counts of sources of project " + componentUuid); - massUpdate.execute(PopulateFileSourceLineCount::handle); - } - } - - private static boolean handle(Select.Row row, SqlStatement update) throws SQLException { - String rowUuid = row.getString(1); - String rawData = row.getNullableString(2); - - int lineCount = rawData == null ? 0 : Iterables.size(FileSourceDto.LINES_HASHES_SPLITTER.split(rawData)); - update.setInt(1, lineCount); - update.setString(2, rowUuid); - return true; - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChange.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChange.java deleted file mode 100644 index d959da57a01..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChange.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import org.sonar.server.platform.db.migration.step.MigrationStep; - -/** - * Marker interface of {@link MigrationStep} for the implementations to be run in - * {@link org.sonar.ce.task.projectanalysis.step.DbMigrationsStep DbMigrationsStep}. - *

- * {@link MigrationStep} execute during project report analysis should perform only data change operations. - */ -public interface ProjectAnalysisDataChange extends MigrationStep { - -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChanges.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChanges.java deleted file mode 100644 index 441f476c524..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChanges.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import java.util.List; - -public interface ProjectAnalysisDataChanges { - /** - * @return {@link ProjectAnalysisDataChange} instances to be executed in order. - */ - List getDataChanges(); -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChangesImpl.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChangesImpl.java deleted file mode 100644 index b493dee3211..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChangesImpl.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.ImmutableList.of; -import static org.sonar.core.util.stream.MoreCollectors.toList; -import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex; - -/** - * Implementation of {@link ProjectAnalysisDataChanges} based on an ordered list of {@link ProjectAnalysisDataChange} - * classes and the {@link ProjectAnalysisDataChange} instances which can be injected by the container. - */ -public class ProjectAnalysisDataChangesImpl implements ProjectAnalysisDataChanges { - private static final List> DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION = of( - PopulateFileSourceLineCount.class); - private final List dataChangeInstances; - - public ProjectAnalysisDataChangesImpl(ProjectAnalysisDataChange[] dataChanges) { - checkArgument(dataChanges.length == DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION.size(), - "Number of ProjectAnalysisDataChange instance available (%s) is inconsistent with the number of declared ProjectAnalysisDataChange types (%s)", - dataChanges.length, - DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION.size()); - Map, ProjectAnalysisDataChange> dataChangesByClass = Arrays.stream(dataChanges) - .collect(uniqueIndex(ProjectAnalysisDataChange::getClass)); - dataChangeInstances = DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION.stream() - .map(dataChangesByClass::get) - .filter(Objects::nonNull) - .collect(toList(DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION.size())); - checkState(dataChangeInstances.size() == DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION.size(), - "Some of the ProjectAnalysisDataChange type declared have no instance in the container"); - } - - static List> getDataChangeClasses() { - return DATA_CHANGE_CLASSES_IN_ORDER_OF_EXECUTION; - } - - @Override - public List getDataChanges() { - return dataChangeInstances; - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/package-info.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/package-info.java deleted file mode 100644 index 79bb110e2d4..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/dbmigration/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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. - */ -@ParametersAreNonnullByDefault -package org.sonar.ce.task.projectanalysis.dbmigration; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DbMigrationsStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DbMigrationsStep.java deleted file mode 100644 index 85cc9ecc0dd..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/DbMigrationsStep.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.ce.task.projectanalysis.step; - -import java.sql.SQLException; -import org.sonar.ce.task.projectanalysis.dbmigration.ProjectAnalysisDataChange; -import org.sonar.ce.task.projectanalysis.dbmigration.ProjectAnalysisDataChanges; -import org.sonar.ce.task.step.ComputationStep; - -public class DbMigrationsStep implements ComputationStep { - private final ProjectAnalysisDataChanges dataChanges; - - public DbMigrationsStep(ProjectAnalysisDataChanges dataChanges) { - this.dataChanges = dataChanges; - } - - @Override - public String getDescription() { - return "Execute DB migrations for current project"; - } - - @Override - public void execute(ComputationStep.Context context) { - dataChanges.getDataChanges().forEach(DbMigrationsStep::execute); - } - - private static void execute(ProjectAnalysisDataChange dataChange) { - try { - dataChange.execute(); - } catch (SQLException e) { - throw new IllegalStateException("Failed to perform DB migration for project", e); - } - } - -} diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java index c7d5ca07703..9eda77e3c9a 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/ReportComputationSteps.java @@ -39,7 +39,6 @@ public class ReportComputationSteps extends AbstractComputationSteps { ExtractReportStep.class, PersistScannerContextStep.class, PersistAnalysisWarningsStep.class, - DbMigrationsStep.class, GenerateAnalysisUuid.class, // Builds Component tree diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/DbMigrationModuleTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/DbMigrationModuleTest.java deleted file mode 100644 index 31cf66b94e8..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/DbMigrationModuleTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import java.util.Objects; -import org.junit.Test; -import org.sonar.core.platform.ComponentContainer; - -import static org.assertj.core.api.Assertions.assertThat; - -public class DbMigrationModuleTest { - private DbMigrationModule underTest = new DbMigrationModule(); - - @Test - public void module_configure_ProjectAnalysisDataChanges_implementation() { - ComponentContainer container = new ComponentContainer(); - - underTest.configure(container); - - assertThat(container.getPicoContainer().getComponentAdapters(ProjectAnalysisDataChanges.class)) - .hasSize(1); - } - - @Test - public void module_includes_ProjectAnalysisDataChange_classes() { - ComponentContainer container = new ComponentContainer(); - - underTest.configure(container); - - assertThat(ProjectAnalysisDataChangesImpl.getDataChangeClasses() - .stream() - .map(t -> container.getPicoContainer().getComponentAdapter(t)) - .filter(Objects::nonNull)).hasSize(ProjectAnalysisDataChangesImpl.getDataChangeClasses().size()); - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java deleted file mode 100644 index 139ce9547c0..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/PopulateFileSourceLineCountTest.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import java.sql.SQLException; -import java.util.Optional; -import java.util.Random; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import javax.annotation.Nullable; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.api.utils.System2; -import org.sonar.ce.task.CeTask; -import org.sonar.core.util.SequenceUuidFactory; -import org.sonar.core.util.UuidFactory; -import org.sonar.db.DbTester; - -import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.sonar.db.source.FileSourceDto.LINE_COUNT_NOT_POPULATED; - -public class PopulateFileSourceLineCountTest { - - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Rule - public DbTester db = DbTester.create(System2.INSTANCE); - - private UuidFactory uuidFactory = new SequenceUuidFactory(); - - private Random random = new Random(); - private CeTask ceTask = mock(CeTask.class); - private PopulateFileSourceLineCount underTest = new PopulateFileSourceLineCount(db.database(), ceTask); - - @Test - public void execute_has_no_effect_on_empty_table() throws SQLException { - String projectUuid = randomAlphanumeric(4); - when(ceTask.getComponent()).thenReturn(newComponent(projectUuid)); - - underTest.execute(); - } - - @Test - public void execute_populates_line_count_of_any_type() throws SQLException { - String projectUuid = randomAlphanumeric(4); - String fileUuid = randomAlphanumeric(5); - when(ceTask.getComponent()).thenReturn(newComponent(projectUuid)); - int lineCount = 1 + random.nextInt(15); - insertUnpopulatedFileSource(projectUuid, fileUuid, lineCount); - assertThat(getLineCountByFileUuid(fileUuid)).isEqualTo(LINE_COUNT_NOT_POPULATED); - - underTest.execute(); - - assertThat(getLineCountByFileUuid(fileUuid)).isEqualTo(lineCount); - } - - @Test - public void execute_changes_only_file_source_with_LINE_COUNT_NOT_POPULATED_value() throws SQLException { - String projectUuid = randomAlphanumeric(4); - String fileUuid1 = randomAlphanumeric(5); - String fileUuid2 = randomAlphanumeric(6); - String fileUuid3 = randomAlphanumeric(7); - int lineCountFile1 = 100 + random.nextInt(15); - int lineCountFile2 = 50 + random.nextInt(15); - int lineCountFile3 = 150 + random.nextInt(15); - - when(ceTask.getComponent()).thenReturn(newComponent(projectUuid)); - insertPopulatedFileSource(projectUuid, fileUuid1, lineCountFile1); - int badLineCountFile2 = insertInconsistentPopulatedFileSource(projectUuid, fileUuid2, lineCountFile2); - insertUnpopulatedFileSource(projectUuid, fileUuid3, lineCountFile3); - assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(lineCountFile1); - assertThat(getLineCountByFileUuid(fileUuid2)).isEqualTo(badLineCountFile2); - assertThat(getLineCountByFileUuid(fileUuid3)).isEqualTo(LINE_COUNT_NOT_POPULATED); - - underTest.execute(); - - assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(lineCountFile1); - assertThat(getLineCountByFileUuid(fileUuid2)).isEqualTo(badLineCountFile2); - assertThat(getLineCountByFileUuid(fileUuid3)).isEqualTo(lineCountFile3); - } - - @Test - public void execute_changes_only_file_source_of_CeTask_component_uuid() throws SQLException { - String projectUuid1 = randomAlphanumeric(4); - String projectUuid2 = randomAlphanumeric(5); - String fileUuid1 = randomAlphanumeric(6); - String fileUuid2 = randomAlphanumeric(7); - int lineCountFile1 = 100 + random.nextInt(15); - int lineCountFile2 = 30 + random.nextInt(15); - - when(ceTask.getComponent()).thenReturn(newComponent(projectUuid1)); - insertUnpopulatedFileSource(projectUuid1, fileUuid1, lineCountFile1); - insertUnpopulatedFileSource(projectUuid2, fileUuid2, lineCountFile2); - - underTest.execute(); - - assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(lineCountFile1); - assertThat(getLineCountByFileUuid(fileUuid2)).isEqualTo(LINE_COUNT_NOT_POPULATED); - } - - @Test - public void execute_set_line_count_to_zero_when_file_source_has_no_line_hashes() throws SQLException { - String projectUuid = randomAlphanumeric(4); - String fileUuid1 = randomAlphanumeric(5); - - when(ceTask.getComponent()).thenReturn(newComponent(projectUuid)); - insertFileSource(projectUuid, fileUuid1, null, LINE_COUNT_NOT_POPULATED); - - underTest.execute(); - - assertThat(getLineCountByFileUuid(fileUuid1)).isZero(); - } - - @Test - public void execute_set_line_count_to_1_when_file_source_has_empty_line_hashes() throws SQLException { - String projectUuid = randomAlphanumeric(4); - String fileUuid1 = randomAlphanumeric(5); - - when(ceTask.getComponent()).thenReturn(newComponent(projectUuid)); - insertFileSource(projectUuid, fileUuid1, "", LINE_COUNT_NOT_POPULATED); - - underTest.execute(); - - assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(1); - } - - private int getLineCountByFileUuid(String fileUuid) { - Long res = (Long) db.selectFirst("select line_count as \"LINE_COUNT\" from file_sources where file_uuid = '" + fileUuid + "'") - .get("LINE_COUNT"); - return res.intValue(); - } - - private void insertUnpopulatedFileSource(String projectUuid, String fileUuid, int numberOfHashes) { - String lineHashes = generateLineHashes(numberOfHashes); - - insertFileSource(projectUuid, fileUuid, lineHashes, LINE_COUNT_NOT_POPULATED); - } - - private void insertPopulatedFileSource(String projectUuid, String fileUuid, int lineCount) { - String lineHashes = generateLineHashes(lineCount); - - insertFileSource(projectUuid, fileUuid, lineHashes, lineCount); - } - - private int insertInconsistentPopulatedFileSource(String projectUuid, String fileUuid, int lineCount) { - String lineHashes = generateLineHashes(lineCount); - int badLineCount = lineCount + random.nextInt(6); - - insertFileSource(projectUuid, fileUuid, lineHashes, badLineCount); - - return badLineCount; - } - - private static String generateLineHashes(int numberOfHashes) { - return IntStream.range(0, numberOfHashes) - .mapToObj(String::valueOf) - .collect(Collectors.joining("\n")); - } - - private void insertFileSource(String projectUuid, String fileUuid, @Nullable String lineHashes, int lineCount) { - db.executeInsert( - "FILE_SOURCES", - "UUID", uuidFactory.create(), - "PROJECT_UUID", projectUuid, - "FILE_UUID", fileUuid, - "LINE_HASHES", lineHashes, - "LINE_COUNT", lineCount, - "CREATED_AT", 1_222_333L, - "UPDATED_AT", 1_222_333L); - db.commit(); - } - - private static Optional newComponent(String projectUuid) { - return Optional.of(new CeTask.Component(projectUuid, "key_" + projectUuid, "name_" + projectUuid)); - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChangesImplTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChangesImplTest.java deleted file mode 100644 index 06483837ad7..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/dbmigration/ProjectAnalysisDataChangesImplTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.ce.task.projectanalysis.dbmigration; - -import java.util.List; -import java.util.stream.Collectors; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.sonar.ce.task.CeTask; -import org.sonar.db.Database; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -public class ProjectAnalysisDataChangesImplTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); - - @Test - public void constructor_throws_IAE_if_argument_is_empty() { - ProjectAnalysisDataChange[] empty = new ProjectAnalysisDataChange[0]; - int expectedArraySize = ProjectAnalysisDataChangesImpl.getDataChangeClasses().size(); - - expectedException.expect(IllegalArgumentException.class); - expectedException.expectMessage("Number of ProjectAnalysisDataChange instance available (0) is inconsistent with " + - "the number of declared ProjectAnalysisDataChange types (" + expectedArraySize + ")"); - - new ProjectAnalysisDataChangesImpl(empty); - } - - @Test - public void constructor_throws_ISE_if_an_instance_of_declared_class_is_missing() { - ProjectAnalysisDataChange[] wrongInstance = new ProjectAnalysisDataChange[] { - mock(ProjectAnalysisDataChange.class) - }; - - expectedException.expect(IllegalStateException.class); - expectedException.expectMessage("Some of the ProjectAnalysisDataChange type declared have no instance in the container"); - - new ProjectAnalysisDataChangesImpl(wrongInstance); - - } - - @Test - public void getDataChanges_returns_instances_of_classes_in_order_defined_by_getDataChangeClasses() { - Database database = mock(Database.class); - CeTask ceTask = mock(CeTask.class); - ProjectAnalysisDataChangesImpl underTest = new ProjectAnalysisDataChangesImpl(new ProjectAnalysisDataChange[] { - new PopulateFileSourceLineCount(database, ceTask) - }); - - List dataChanges = underTest.getDataChanges(); - - List> dataChangeClasses = dataChanges - .stream() - .map(ProjectAnalysisDataChange::getClass) - .collect(Collectors.toList()); - assertThat(dataChangeClasses).isEqualTo(ProjectAnalysisDataChangesImpl.getDataChangeClasses()); - } -} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DbMigrationsStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DbMigrationsStepTest.java deleted file mode 100644 index 81d9de50a89..00000000000 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/DbMigrationsStepTest.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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.ce.task.projectanalysis.step; - -import com.google.common.collect.ImmutableList; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.Random; -import java.util.stream.IntStream; -import org.junit.Test; -import org.mockito.InOrder; -import org.mockito.Mockito; -import org.sonar.ce.task.projectanalysis.dbmigration.ProjectAnalysisDataChange; -import org.sonar.ce.task.projectanalysis.dbmigration.ProjectAnalysisDataChanges; -import org.sonar.ce.task.step.TestComputationStepContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class DbMigrationsStepTest { - private ProjectAnalysisDataChanges projectAnalysisDataChanges = mock(ProjectAnalysisDataChanges.class); - - private DbMigrationsStep underTest = new DbMigrationsStep(projectAnalysisDataChanges); - - @Test - public void execute_has_no_effect_if_there_is_no_DataChange() { - underTest.execute(new TestComputationStepContext()); - } - - @Test - public void execute_calls_execute_on_DataChange_instances_in_order_provided_by_ProjectAnalysisDataChanges() { - ProjectAnalysisDataChange[] dataChanges = IntStream.range(0, 5 + new Random().nextInt(5)) - .mapToObj(i -> mock(ProjectAnalysisDataChange.class)) - .toArray(ProjectAnalysisDataChange[]::new); - InOrder inOrder = Mockito.inOrder(dataChanges); - when(projectAnalysisDataChanges.getDataChanges()).thenReturn(Arrays.asList(dataChanges)); - - underTest.execute(new TestComputationStepContext()); - - Arrays.stream(dataChanges).forEach(t -> { - try { - inOrder.verify(t).execute(); - } catch (SQLException e) { - throw new RuntimeException("mock execute method throw an exception??!!??", e); - } - }); - } - - @Test - public void execute_stops_executing_and_throws_ISE_at_first_failing_DataChange() throws SQLException { - ProjectAnalysisDataChange okMock1 = mock(ProjectAnalysisDataChange.class); - ProjectAnalysisDataChange okMock2 = mock(ProjectAnalysisDataChange.class); - ProjectAnalysisDataChange failingMock1 = mock(ProjectAnalysisDataChange.class); - SQLException expected = new SQLException("Faiking DataChange throwing a SQLException"); - doThrow(expected).when(failingMock1).execute(); - ProjectAnalysisDataChange okMock3 = mock(ProjectAnalysisDataChange.class); - ProjectAnalysisDataChange failingMock2 = mock(ProjectAnalysisDataChange.class); - doThrow(new SQLException("Faiking another failing DataChange throwing a SQLException but which should never be thrown")) - .when(failingMock2) - .execute(); - ProjectAnalysisDataChange okMock4 = mock(ProjectAnalysisDataChange.class); - InOrder inOrder = Mockito.inOrder(okMock1, okMock2, failingMock1, okMock3, failingMock2, okMock4); - when(projectAnalysisDataChanges.getDataChanges()).thenReturn(ImmutableList.of( - okMock1, okMock2, failingMock1, okMock3, failingMock2, okMock4)); - - try { - underTest.execute(new TestComputationStepContext()); - fail("A IllegalStateException should have been thrown"); - } catch (IllegalStateException e) { - assertThat(e) - .hasCause(expected); - inOrder.verify(okMock1).execute(); - inOrder.verify(okMock2).execute(); - inOrder.verify(failingMock1).execute(); - inOrder.verifyNoMoreInteractions(); - } - } - - @Test - public void verify_description() { - assertThat(underTest.getDescription()).isNotEmpty(); - } -} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCount.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCount.java new file mode 100644 index 00000000000..d2f05625c15 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCount.java @@ -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.v85; + +import java.sql.SQLException; +import org.apache.commons.lang.StringUtils; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; +import org.sonar.server.platform.db.migration.step.Select; +import org.sonar.server.platform.db.migration.step.SqlStatement; + +public class PopulateFileSourceLineCount extends DataChange { + static final int LINE_COUNT_NOT_POPULATED = -1; + private static final String NEW_LINE = "\n"; + + public PopulateFileSourceLineCount(Database database) { + super(database); + } + + @Override + protected void execute(Context context) throws SQLException { + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select uuid, line_hashes from file_sources where line_count = ?").setInt(1, LINE_COUNT_NOT_POPULATED); + massUpdate.update("update file_sources set line_count = ? where uuid = ?"); + massUpdate.rowPluralName("line counts of file sources"); + massUpdate.execute(PopulateFileSourceLineCount::handle); + } + + private static boolean handle(Select.Row row, SqlStatement update) throws SQLException { + String rowUuid = row.getString(1); + String rawData = row.getNullableString(2); + + int lineCount = rawData == null ? 0 : (StringUtils.countMatches(rawData, NEW_LINE) + 1); + update.setInt(1, lineCount); + update.setString(2, rowUuid); + return true; + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCountTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCountTest.java new file mode 100644 index 00000000000..a8f3ba460f4 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCountTest.java @@ -0,0 +1,159 @@ +/* + * 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.v85; + +import java.sql.SQLException; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import javax.annotation.Nullable; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.core.util.SequenceUuidFactory; +import org.sonar.core.util.UuidFactory; +import org.sonar.db.CoreDbTester; + +import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric; +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.server.platform.db.migration.version.v85.PopulateFileSourceLineCount.LINE_COUNT_NOT_POPULATED; + +public class PopulateFileSourceLineCountTest { + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(PopulateFileSourceLineCountTest.class, "schema.sql"); + + private UuidFactory uuidFactory = new SequenceUuidFactory(); + + private PopulateFileSourceLineCount underTest = new PopulateFileSourceLineCount(db.database()); + + @Test + public void execute_has_no_effect_on_empty_table() throws SQLException { + underTest.execute(); + assertThat(db.countRowsOfTable("file_sources")).isZero(); + } + + @Test + public void execute_populates_line_count_of_any_type() throws SQLException { + String projectUuid = randomAlphanumeric(4); + String fileUuid = randomAlphanumeric(5); + int lineCount = 10; + insertUnpopulatedFileSource(projectUuid, fileUuid, lineCount); + assertThat(getLineCountByFileUuid(fileUuid)).isEqualTo(LINE_COUNT_NOT_POPULATED); + + underTest.execute(); + + assertThat(getLineCountByFileUuid(fileUuid)).isEqualTo(lineCount); + } + + @Test + public void execute_changes_only_file_source_with_LINE_COUNT_NOT_POPULATED_value() throws SQLException { + String projectUuid = randomAlphanumeric(4); + String fileUuid1 = randomAlphanumeric(5); + String fileUuid2 = randomAlphanumeric(6); + String fileUuid3 = randomAlphanumeric(7); + int lineCountFile1 = 10; + int lineCountFile2 = 50; + int lineCountFile3 = 150; + + insertPopulatedFileSource(projectUuid, fileUuid1, lineCountFile1); + int badLineCountFile2 = insertInconsistentPopulatedFileSource(projectUuid, fileUuid2, lineCountFile2); + insertUnpopulatedFileSource(projectUuid, fileUuid3, lineCountFile3); + assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(lineCountFile1); + assertThat(getLineCountByFileUuid(fileUuid2)).isEqualTo(badLineCountFile2); + assertThat(getLineCountByFileUuid(fileUuid3)).isEqualTo(LINE_COUNT_NOT_POPULATED); + + underTest.execute(); + + assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(lineCountFile1); + assertThat(getLineCountByFileUuid(fileUuid2)).isEqualTo(badLineCountFile2); + assertThat(getLineCountByFileUuid(fileUuid3)).isEqualTo(lineCountFile3); + } + + @Test + public void execute_set_line_count_to_zero_when_file_source_has_no_line_hashes() throws SQLException { + String projectUuid = randomAlphanumeric(4); + String fileUuid1 = randomAlphanumeric(5); + + insertFileSource(projectUuid, fileUuid1, null, LINE_COUNT_NOT_POPULATED); + + underTest.execute(); + + assertThat(getLineCountByFileUuid(fileUuid1)).isZero(); + } + + @Test + public void execute_set_line_count_to_1_when_file_source_has_empty_line_hashes() throws SQLException { + String projectUuid = randomAlphanumeric(4); + String fileUuid1 = randomAlphanumeric(5); + + insertFileSource(projectUuid, fileUuid1, "", LINE_COUNT_NOT_POPULATED); + + underTest.execute(); + + assertThat(getLineCountByFileUuid(fileUuid1)).isEqualTo(1); + } + + private int getLineCountByFileUuid(String fileUuid) { + Long res = (Long) db.selectFirst("select line_count as \"LINE_COUNT\" from file_sources where file_uuid = '" + fileUuid + "'") + .get("LINE_COUNT"); + return res.intValue(); + } + + private void insertUnpopulatedFileSource(String projectUuid, String fileUuid, int numberOfHashes) { + String lineHashes = generateLineHashes(numberOfHashes); + + insertFileSource(projectUuid, fileUuid, lineHashes, LINE_COUNT_NOT_POPULATED); + } + + private void insertPopulatedFileSource(String projectUuid, String fileUuid, int lineCount) { + String lineHashes = generateLineHashes(lineCount); + + insertFileSource(projectUuid, fileUuid, lineHashes, lineCount); + } + + private int insertInconsistentPopulatedFileSource(String projectUuid, String fileUuid, int lineCount) { + String lineHashes = generateLineHashes(lineCount); + int badLineCount = lineCount + 6; + + insertFileSource(projectUuid, fileUuid, lineHashes, badLineCount); + + return badLineCount; + } + + private static String generateLineHashes(int numberOfHashes) { + return IntStream.range(0, numberOfHashes) + .mapToObj(String::valueOf) + .collect(Collectors.joining("\n")); + } + + private void insertFileSource(String projectUuid, String fileUuid, @Nullable String lineHashes, int lineCount) { + db.executeInsert( + "FILE_SOURCES", + "UUID", uuidFactory.create(), + "PROJECT_UUID", projectUuid, + "FILE_UUID", fileUuid, + "LINE_HASHES", lineHashes, + "LINE_COUNT", lineCount, + "CREATED_AT", 1_222_333L, + "UPDATED_AT", 1_222_333L); + } +} diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCountTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCountTest/schema.sql new file mode 100644 index 00000000000..261f2992115 --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v85/PopulateFileSourceLineCountTest/schema.sql @@ -0,0 +1,18 @@ +CREATE TABLE "FILE_SOURCES"( + "PROJECT_UUID" VARCHAR(50) NOT NULL, + "FILE_UUID" VARCHAR(50) NOT NULL, + "LINE_HASHES" CLOB(2147483647), + "LINE_HASHES_VERSION" INTEGER, + "DATA_HASH" VARCHAR(50), + "SRC_HASH" VARCHAR(50), + "REVISION" VARCHAR(100), + "LINE_COUNT" INTEGER NOT NULL, + "BINARY_DATA" BLOB, + "CREATED_AT" BIGINT NOT NULL, + "UPDATED_AT" BIGINT NOT NULL, + "UUID" VARCHAR(40) NOT NULL +); +ALTER TABLE "FILE_SOURCES" ADD CONSTRAINT "PK_FILE_SOURCES" PRIMARY KEY("UUID"); +CREATE UNIQUE INDEX "FILE_SOURCES_FILE_UUID" ON "FILE_SOURCES"("FILE_UUID"); +CREATE INDEX "FILE_SOURCES_PROJECT_UUID" ON "FILE_SOURCES"("PROJECT_UUID"); +CREATE INDEX "FILE_SOURCES_UPDATED_AT" ON "FILE_SOURCES"("UPDATED_AT");