From ace9a50d55d831ec71b7db421aa04d1198392c6c Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Wed, 23 Oct 2019 15:33:39 -0500 Subject: [PATCH] SONAR-12689 Separate storage of projects/apps from their components and branches --- .../component/ProjectPersister.java | 74 +++++++ ...ProjectAnalysisTaskContainerPopulator.java | 2 + .../step/PersistComponentsStep.java | 6 +- .../component/BranchPersisterImplTest.java | 18 +- .../ConfigurationRepositoryTest.java | 2 +- .../component/ProjectPersisterTest.java | 115 ++++++++++ .../ReferenceBranchComponentUuidsTest.java | 2 +- .../SiblingComponentsWithOpenIssuesTest.java | 6 +- .../ProjectTrackerBaseLazyInputTest.java | 2 +- .../issue/SiblingsIssueMergerTest.java | 2 +- .../step/BuildComponentTreeStepTest.java | 2 +- .../step/LoadPeriodsStepTest.java | 6 +- .../step/PersistComponentsStepTest.java | 4 +- .../step/ReportPersistComponentsStepTest.java | 16 +- .../step/SendIssueNotificationsStepTest.java | 6 +- .../step/ValidateProjectStepTest.java | 4 +- .../step/ViewsPersistComponentsStepTest.java | 6 +- .../ComputeEngineContainerImplTest.java | 2 +- .../java/org/sonar/db/version/SqTables.java | 1 + .../src/main/java/org/sonar/db/DaoModule.java | 2 + .../src/main/java/org/sonar/db/DbClient.java | 7 + .../src/main/java/org/sonar/db/MyBatis.java | 4 + .../db/alm/setting/ProjectAlmSettingDao.java | 9 +- .../org/sonar/db/component/BranchDao.java | 14 ++ .../org/sonar/db/component/BranchMapper.java | 4 + .../org/sonar/db/component/ComponentDao.java | 8 - .../db/component/ComponentKeyUpdaterDao.java | 34 ++- .../component/ComponentKeyUpdaterMapper.java | 4 +- .../java/org/sonar/db/issue/IssueTesting.java | 14 +- .../ProjectMeasuresIndexerIterator.java | 9 +- .../java/org/sonar/db/project/ProjectDao.java | 88 ++++++++ .../java/org/sonar/db/project/ProjectDto.java | 184 ++++++++++++++++ .../org/sonar/db/project/ProjectMapper.java | 56 +++++ .../org/sonar/db/project/ProjectQuery.java | 201 +++++++++++++++++ .../org/sonar/db/project/package-info.java | 24 ++ .../org/sonar/db/property/PropertiesDao.java | 2 +- .../org/sonar/db/purge/PurgeCommands.java | 7 + .../java/org/sonar/db/purge/PurgeDao.java | 4 +- .../java/org/sonar/db/purge/PurgeMapper.java | 2 + .../ProjectQgateAssociationDao.java | 6 +- .../ProjectQgateAssociationMapper.java | 2 +- .../sonar/db/qualitygate/QualityGateDao.java | 4 +- .../db/qualityprofile/QualityProfileDao.java | 22 +- .../main/java/org/sonar/db/user/UserDao.java | 5 + .../java/org/sonar/db/webhook/WebhookDao.java | 9 +- .../sonar/db/alm/ProjectAlmBindingMapper.xml | 2 +- .../org/sonar/db/component/BranchMapper.xml | 10 + .../component/ComponentKeyUpdaterMapper.xml | 18 +- .../sonar/db/component/ComponentMapper.xml | 102 ++++----- .../org/sonar/db/component/SnapshotMapper.xml | 6 +- .../db/duplication/DuplicationMapper.xml | 2 +- .../org/sonar/db/issue/IssueMapper.xml | 36 +-- .../sonar/db/measure/LiveMeasureMapper.xml | 8 +- .../org/sonar/db/measure/MeasureMapper.xml | 2 +- .../db/organization/OrganizationMapper.xml | 6 +- .../db/permission/AuthorizationMapper.xml | 28 +-- .../db/permission/GroupPermissionMapper.xml | 2 +- .../db/permission/UserPermissionMapper.xml | 6 +- .../org/sonar/db/project/ProjectMapper.xml | 144 ++++++++++++ .../InternalComponentPropertiesMapper.xml | 2 +- .../sonar/db/property/PropertiesMapper.xml | 12 +- .../org/sonar/db/purge/PurgeMapper.xml | 20 +- .../ProjectQgateAssociationMapper.xml | 8 +- .../qualityprofile/QualityProfileMapper.xml | 8 +- .../org/sonar/db/source/FileSourceMapper.xml | 2 +- server/sonar-db-dao/src/schema/schema-sq.ddl | 96 ++++---- .../test/java/org/sonar/db/DaoModuleTest.java | 2 +- .../alm/setting/ProjectAlmSettingDaoTest.java | 22 +- .../org/sonar/db/component/BranchDaoTest.java | 47 +++- .../sonar/db/component/ComponentDaoTest.java | 34 +-- .../component/ComponentKeyUpdaterDaoTest.java | 27 +-- .../sonar/db/component/SnapshotDaoTest.java | 10 +- .../java/org/sonar/db/issue/IssueDaoTest.java | 4 +- .../sonar/db/measure/LiveMeasureDaoTest.java | 12 +- .../ProjectMeasuresIndexerIteratorTest.java | 5 +- .../db/organization/OrganizationDaoTest.java | 13 +- .../org/sonar/db/project/ProjectDaoTest.java | 172 +++++++++++++++ .../org/sonar/db/purge/PurgeCommandsTest.java | 32 ++- .../java/org/sonar/db/purge/PurgeDaoTest.java | 122 +++++------ .../ProjectQgateAssociationDaoTest.java | 43 ++-- .../db/qualitygate/QualityGateDaoTest.java | 6 +- .../qualityprofile/QualityProfileDaoTest.java | 45 ++-- .../java/org/sonar/db/user/UserDaoTest.java | 3 +- .../org/sonar/db/webhook/WebhookDaoTest.java | 16 +- .../db/almsettings/AlmSettingsDbTester.java | 10 +- .../db/almsettings/AlmSettingsTesting.java | 22 +- .../sonar/db/component/ComponentDbTester.java | 206 ++++++++++++------ .../sonar/db/component/ComponentTesting.java | 44 +++- .../sonar/db/component/SnapshotTesting.java | 11 +- .../org/sonar/db/issue/IssueDbTester.java | 14 +- .../db/qualitygate/QualityGateDbTester.java | 8 +- .../QualityProfileDbTester.java | 4 +- .../java/org/sonar/db/user/UserDbTester.java | 1 + .../org/sonar/db/webhook/WebhookDbTester.java | 3 +- .../org/sonar/db/webhook/WebhookTesting.java | 13 +- .../version/v81/CreateProjectsTable.java | 129 +++++++++++ .../db/migration/version/v81/DbVersion81.java | 6 +- .../version/v81/PopulateProjectsTable.java | 62 ++++++ .../v81/RenameProjectsTableToComponents.java | 35 +++ .../version/v81/CreateProjectsTableTest.java | 65 ++++++ .../version/v81/DbVersion81Test.java | 2 +- .../v81/PopulateProjectsTableTest.java | 122 +++++++++++ .../RenameProjectsTableToComponentsTest.java | 68 ++++++ .../v81/PopulateProjectsTableTest/schema.sql | 64 ++++++ .../schema.sql | 48 ++++ .../org/sonar/server/es/ProjectIndexers.java | 24 ++ .../index/IssueIteratorForSingleChunk.java | 2 +- .../measure/index/ProjectMeasuresIndexer.java | 3 +- .../org/sonar/server/project/Project.java | 5 + .../server/qualitygate/QualityGateFinder.java | 10 +- .../org/sonar/server/webhook/WebHooks.java | 6 +- .../sonar/server/webhook/WebHooksImpl.java | 19 +- .../index/ProjectMeasuresIndexerTest.java | 5 +- .../qualitygate/QualityGateFinderTest.java | 12 +- .../server/view/index/ViewIndexerTest.java | 2 +- .../webhook/SynchronousWebHooksImplTest.java | 36 +-- .../changeevent/QGChangeEvent.java | 12 +- .../QGChangeEventListenersImpl.java | 29 ++- .../QGChangeEventListenersImplTest.java | 46 ++-- .../changeevent/QGChangeEventTest.java | 6 +- .../server/user/AbstractUserSession.java | 35 +++ .../sonar/server/user/ServerUserSession.java | 3 + .../server/user/ThreadLocalUserSession.java | 15 ++ .../org/sonar/server/user/UserSession.java | 13 +- .../tester/AbstractMockUserSession.java | 28 +++ .../sonar/server/tester/UserSessionRule.java | 19 ++ .../sonar/server/platform/BackendCleanup.java | 2 +- .../webhook/WebhookQGChangeEventListener.java | 10 +- .../server/platform/BackendCleanupTest.java | 3 + .../TelemetryDataLoaderImplTest.java | 6 +- .../WebhookQGChangeEventListenerTest.java | 83 ++++--- .../index/PermissionIndexerDao.java | 66 +++--- .../issue/index/IssueIndexFiltersTest.java | 6 +- .../IssueIndexProjectStatisticsTest.java | 4 +- .../server/issue/index/IssueIndexTest.java | 6 +- .../issue/index/IssueQueryFactoryTest.java | 4 +- .../sonar/server/badge/ws/MeasureAction.java | 9 +- .../server/badge/ws/ProjectBadgesSupport.java | 44 ++-- .../server/badge/ws/QualityGateAction.java | 9 +- .../sonar/server/batch/ProjectDataLoader.java | 15 +- .../server/branch/pr/ws/DeleteAction.java | 13 +- .../sonar/server/branch/pr/ws/ListAction.java | 22 +- .../sonar/server/branch/ws/DeleteAction.java | 19 +- .../sonar/server/branch/ws/ListAction.java | 43 ++-- .../sonar/server/branch/ws/RenameAction.java | 16 +- .../SetAutomaticDeletionProtectionAction.java | 12 +- .../server/ce/queue/ReportSubmitter.java | 3 +- .../server/ce/ws/AnalysisStatusAction.java | 50 ++--- .../component/ComponentCleanerService.java | 43 ++-- .../server/component/ComponentFinder.java | 52 ++++- .../server/component/ComponentService.java | 31 +-- .../server/component/ComponentUpdater.java | 38 +++- .../measure/live/LiveMeasureComputerImpl.java | 30 ++- .../measure/live/LiveQualityGateComputer.java | 3 +- .../live/LiveQualityGateComputerImpl.java | 8 +- .../server/newcodeperiod/ws/ListAction.java | 18 +- .../server/newcodeperiod/ws/SetAction.java | 96 ++++---- .../server/newcodeperiod/ws/ShowAction.java | 71 +++--- .../server/newcodeperiod/ws/UnsetAction.java | 51 ++--- .../organization/ws/OrganizationDeleter.java | 17 +- .../server/project/ws/BulkDeleteAction.java | 11 +- .../project/ws/BulkUpdateKeyAction.java | 25 +-- .../sonar/server/project/ws/DeleteAction.java | 8 +- .../sonar/server/project/ws/SearchAction.java | 2 +- .../server/project/ws/UpdateKeyAction.java | 21 +- .../project/ws/UpdateVisibilityAction.java | 4 +- .../projectanalysis/ws/CreateEventAction.java | 37 ++-- .../projectanalysis/ws/SetBaselineAction.java | 48 ++-- .../ws/UnsetBaselineAction.java | 31 ++- .../server/projectlink/ws/CreateAction.java | 13 +- .../server/projectlink/ws/ProjectLinksWs.java | 13 -- .../server/projectlink/ws/SearchAction.java | 31 ++- .../sonar/server/projecttag/ws/SetAction.java | 25 ++- .../server/qualitygate/ws/DeselectAction.java | 36 +-- .../qualitygate/ws/GetByProjectAction.java | 8 +- .../qualitygate/ws/ProjectStatusAction.java | 59 +++-- .../qualitygate/ws/QualityGatesWsSupport.java | 44 +++- .../server/qualitygate/ws/SelectAction.java | 41 +--- .../qualityprofile/ws/AddProjectAction.java | 12 +- .../ws/RemoveProjectAction.java | 12 +- .../qualityprofile/ws/SearchAction.java | 22 +- .../sonar/server/ui/ws/ComponentAction.java | 2 +- .../sonar/server/user/ws/CurrentAction.java | 26 ++- .../server/user/ws/SetHomepageAction.java | 8 +- .../sonar/server/webhook/ws/CreateAction.java | 26 +-- .../sonar/server/webhook/ws/DeleteAction.java | 12 +- .../sonar/server/webhook/ws/ListAction.java | 21 +- .../sonar/server/webhook/ws/UpdateAction.java | 14 +- .../webhook/ws/WebhookDeliveriesAction.java | 44 ++-- .../webhook/ws/WebhookDeliveryAction.java | 16 +- .../server/webhook/ws/WebhookSupport.java | 10 +- .../server/webhook/ws/WebhookWsSupport.java | 10 +- .../server/badge/ws/MeasureActionTest.java | 10 +- .../badge/ws/QualityGateActionTest.java | 8 +- .../server/batch/ProjectDataLoaderTest.java | 18 +- .../server/branch/pr/ws/DeleteActionTest.java | 11 +- .../server/branch/pr/ws/ListActionTest.java | 34 +-- .../server/branch/ws/DeleteActionTest.java | 13 +- .../server/branch/ws/ListActionTest.java | 46 ++-- .../server/branch/ws/RenameActionTest.java | 10 +- ...AutomaticDeletionProtectionActionTest.java | 12 +- .../ce/queue/BranchReportSubmitterTest.java | 14 +- .../server/ce/ws/ActivityActionTest.java | 4 +- .../ce/ws/AnalysisStatusActionTest.java | 39 +--- .../server/ce/ws/ComponentActionTest.java | 6 +- .../sonar/server/ce/ws/TaskActionTest.java | 2 +- .../ComponentCleanerServiceTest.java | 105 +++------ .../server/component/ComponentFinderTest.java | 16 +- .../component/ComponentServiceTest.java | 7 +- .../ComponentServiceUpdateKeyTest.java | 66 ++---- .../server/component/ws/AppActionTest.java | 8 +- .../server/component/ws/SearchActionTest.java | 2 +- .../ws/SearchProjectsActionTest.java | 2 +- .../server/component/ws/ShowActionTest.java | 6 +- .../component/ws/SuggestionsActionTest.java | 2 +- .../server/component/ws/TreeActionTest.java | 6 +- .../ws/DuplicationsParserTest.java | 4 +- .../server/duplication/ws/ShowActionTest.java | 8 +- .../ws/ShowResponseBuilderTest.java | 4 +- .../server/favorite/ws/AddActionTest.java | 2 +- .../server/favorite/ws/RemoveActionTest.java | 2 +- .../server/issue/WebIssueStorageTest.java | 8 +- .../server/issue/ws/BulkChangeActionTest.java | 16 +- .../issue/ws/DoTransitionActionTest.java | 2 +- .../server/issue/ws/IssueUpdaterTest.java | 16 +- .../issue/ws/SearchActionComponentsTest.java | 6 +- .../server/issue/ws/SetTagsActionTest.java | 4 +- .../server/issue/ws/SetTypeActionTest.java | 2 +- .../live/LiveMeasureComputerImplTest.java | 14 +- .../live/LiveQualityGateComputerImplTest.java | 13 +- .../measure/ws/ComponentActionTest.java | 2 +- .../measure/ws/ComponentTreeActionTest.java | 6 +- .../server/measure/ws/SearchActionTest.java | 2 +- .../measure/ws/SearchHistoryActionTest.java | 2 +- .../newcodeperiod/ws/ListActionTest.java | 18 +- .../newcodeperiod/ws/SetActionTest.java | 28 +-- .../newcodeperiod/ws/ShowActionTest.java | 18 +- .../newcodeperiod/ws/UnsetActionTest.java | 18 +- .../server/notification/ws/AddActionTest.java | 2 +- .../notification/ws/RemoveActionTest.java | 2 +- .../organization/ws/DeleteActionTest.java | 43 ++-- .../ws/OrganizationDeleterTest.java | 60 ++--- .../permission/ws/AddGroupActionTest.java | 4 +- .../permission/ws/AddUserActionTest.java | 4 +- .../permission/ws/GroupsActionTest.java | 4 +- .../permission/ws/RemoveGroupActionTest.java | 4 +- .../permission/ws/RemoveUserActionTest.java | 4 +- .../SearchProjectPermissionsActionTest.java | 2 +- .../server/permission/ws/UsersActionTest.java | 4 +- .../project/ws/BulkDeleteActionTest.java | 34 ++- .../project/ws/BulkUpdateKeyActionTest.java | 29 ++- .../server/project/ws/DeleteActionTest.java | 24 +- .../server/project/ws/SearchActionTest.java | 2 +- .../ws/SearchMyProjectsActionTest.java | 2 +- .../project/ws/UpdateKeyActionTest.java | 29 +-- .../ws/UpdateVisibilityActionTest.java | 6 +- .../ws/CreateEventActionTest.java | 20 +- .../projectanalysis/ws/DeleteActionTest.java | 4 +- .../ws/SetBaselineActionTest.java | 93 +++----- .../ws/UnsetBaselineActionTest.java | 41 ++-- .../projectlink/ws/CreateActionTest.java | 49 +++-- .../projectlink/ws/SearchActionTest.java | 45 ++-- .../server/projecttag/ws/SetActionTest.java | 70 +++--- .../server/qualitygate/ws/CopyActionTest.java | 3 +- .../qualitygate/ws/CreateActionTest.java | 3 +- .../ws/CreateConditionActionTest.java | 3 +- .../ws/DeleteConditionActionTest.java | 3 +- .../qualitygate/ws/DeselectActionTest.java | 70 ++---- .../qualitygate/ws/DestroyActionTest.java | 17 +- .../ws/GetByProjectActionTest.java | 19 +- .../server/qualitygate/ws/ListActionTest.java | 3 +- .../ws/ProjectStatusActionTest.java | 8 +- .../qualitygate/ws/RenameActionTest.java | 3 +- .../qualitygate/ws/SearchActionTest.java | 68 +++--- .../qualitygate/ws/SelectActionTest.java | 73 +------ .../server/qualitygate/ws/ShowActionTest.java | 3 +- .../ws/UpdateConditionActionTest.java | 3 +- .../QProfileFactoryImplTest.java | 6 +- .../ws/AddProjectActionTest.java | 35 +-- .../qualityprofile/ws/DeleteActionTest.java | 6 +- .../qualityprofile/ws/ProjectsActionTest.java | 45 ++-- .../ws/RemoveProjectActionTest.java | 31 +-- .../qualityprofile/ws/SearchActionTest.java | 57 ++--- .../qualityprofile/ws/ShowActionTest.java | 12 +- .../server/setting/ws/ResetActionTest.java | 6 +- .../server/setting/ws/SetActionTest.java | 2 +- .../server/setting/ws/ValuesActionTest.java | 2 +- .../server/source/ws/HashActionTest.java | 2 +- .../server/source/ws/IndexActionTest.java | 2 +- .../server/source/ws/LinesActionTest.java | 8 +- .../sonar/server/source/ws/RawActionTest.java | 6 +- .../sonar/server/source/ws/ScmActionTest.java | 2 +- .../server/ui/ws/ComponentActionTest.java | 29 +-- .../server/ui/ws/MarketplaceActionTest.java | 2 +- .../user/ws/CurrentActionHomepageTest.java | 2 +- .../server/user/ws/CurrentActionTest.java | 2 +- .../server/user/ws/SetHomepageActionTest.java | 2 +- .../server/webhook/ws/CreateActionTest.java | 11 +- .../server/webhook/ws/DeleteActionTest.java | 5 +- .../server/webhook/ws/ListActionTest.java | 9 +- .../server/webhook/ws/UpdateActionTest.java | 16 +- .../ws/WebhookDeliveriesActionTest.java | 2 +- .../webhook/ws/WebhookDeliveryActionTest.java | 3 +- .../no_author_and_no_authors_facet.json | 20 -- .../no_authors_facet.json | 22 -- .../with_authors_facet.json | 37 ---- 306 files changed, 4307 insertions(+), 2577 deletions(-) create mode 100644 server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectPersister.java create mode 100644 server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ProjectPersisterTest.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDao.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDto.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectQuery.java create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/project/package-info.java create mode 100644 server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml create mode 100644 server/sonar-db-dao/src/test/java/org/sonar/db/project/ProjectDaoTest.java create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/CreateProjectsTable.java create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/PopulateProjectsTable.java create mode 100644 server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v81/RenameProjectsTableToComponents.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/CreateProjectsTableTest.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/PopulateProjectsTableTest.java create mode 100644 server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v81/RenameProjectsTableToComponentsTest.java create mode 100644 server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v81/PopulateProjectsTableTest/schema.sql create mode 100644 server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v81/RenameProjectsTableToComponentsTest/schema.sql delete mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTestOnSonarCloud/no_author_and_no_authors_facet.json delete mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTestOnSonarCloud/no_authors_facet.json delete mode 100644 server/sonar-webserver-webapi/src/test/resources/org/sonar/server/issue/ws/SearchActionTestOnSonarCloud/with_authors_facet.json diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectPersister.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectPersister.java new file mode 100644 index 00000000000..645ca0ddb73 --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ProjectPersister.java @@ -0,0 +1,74 @@ +/* + * 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.component; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.utils.System2; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.project.ProjectDto; + +/** + * Creates or updates the data in table {@code PROJECTS} for the current root. + */ +public class ProjectPersister { + private final DbClient dbClient; + private final TreeRootHolder treeRootHolder; + private final System2 system2; + + public ProjectPersister(DbClient dbClient, TreeRootHolder treeRootHolder, System2 system2) { + this.dbClient = dbClient; + this.treeRootHolder = treeRootHolder; + this.system2 = system2; + } + + public void persist(DbSession dbSession) { + if (shouldSkip(treeRootHolder.getRoot())) { + return; + } + + ProjectDto dbProjectDto = dbClient.projectDao().selectProjectByKey(dbSession, treeRootHolder.getRoot().getKey()) + .orElseThrow(() -> new IllegalStateException("Project has been deleted by end-user during analysis")); + ProjectDto projectDto = toProjectDto(treeRootHolder.getRoot()); + + if (hasChanged(dbProjectDto, projectDto)) { + // insert or update in projects table + dbClient.projectDao().update(dbSession, projectDto); + } + } + + private boolean shouldSkip(Component rootComponent) { + return !rootComponent.getType().equals(Component.Type.PROJECT) && !rootComponent.getType().equals(Component.Type.PROJECT_VIEW); + } + + private boolean hasChanged(ProjectDto dbProject, ProjectDto newProject) { + return !StringUtils.equals(dbProject.getName(), newProject.getName()) || + !StringUtils.equals(dbProject.getDescription(), newProject.getDescription()); + } + + private ProjectDto toProjectDto(Component root) { + ProjectDto projectDto = new ProjectDto(); + projectDto.setUuid(root.getUuid()); + projectDto.setName(root.getName()); + projectDto.setDescription(root.getDescription()); + projectDto.setUpdatedAt(system2.now()); + return projectDto; + } +} 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 6a5e0d89229..c9107ed7d00 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 @@ -34,6 +34,7 @@ import org.sonar.ce.task.projectanalysis.component.BranchPersisterImpl; import org.sonar.ce.task.projectanalysis.component.ConfigurationRepositoryImpl; import org.sonar.ce.task.projectanalysis.component.DbIdsRepositoryImpl; import org.sonar.ce.task.projectanalysis.component.DisabledComponentsHolderImpl; +import org.sonar.ce.task.projectanalysis.component.ProjectPersister; import org.sonar.ce.task.projectanalysis.component.ReferenceBranchComponentUuids; import org.sonar.ce.task.projectanalysis.component.ReportModulesPath; import org.sonar.ce.task.projectanalysis.component.SiblingComponentsWithOpenIssues; @@ -284,6 +285,7 @@ public final class ProjectAnalysisTaskContainerPopulator implements ContainerPop BaseIssuesLoader.class, IssueTrackingDelegator.class, BranchPersisterImpl.class, + ProjectPersister.class, SiblingsIssuesLoader.class, SiblingsIssueMerger.class, NewCodePeriodResolver.class, diff --git a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java index f53c5ad1ca0..2ed3f307a52 100644 --- a/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java +++ b/server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStep.java @@ -44,6 +44,7 @@ import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHold import org.sonar.ce.task.projectanalysis.component.PathAwareCrawler; import org.sonar.ce.task.projectanalysis.component.PathAwareVisitor; import org.sonar.ce.task.projectanalysis.component.PathAwareVisitorAdapter; +import org.sonar.ce.task.projectanalysis.component.ProjectPersister; import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; import org.sonar.ce.task.step.ComputationStep; import org.sonar.core.util.stream.MoreCollectors; @@ -71,11 +72,12 @@ public class PersistComponentsStep implements ComputationStep { private final MutableDisabledComponentsHolder disabledComponentsHolder; private final AnalysisMetadataHolder analysisMetadataHolder; private final BranchPersister branchPersister; + private final ProjectPersister projectPersister; public PersistComponentsStep(DbClient dbClient, TreeRootHolder treeRootHolder, MutableDbIdsRepository dbIdsRepository, System2 system2, MutableDisabledComponentsHolder disabledComponentsHolder, AnalysisMetadataHolder analysisMetadataHolder, - BranchPersister branchPersister) { + BranchPersister branchPersister, ProjectPersister projectPersister) { this.dbClient = dbClient; this.treeRootHolder = treeRootHolder; this.dbIdsRepository = dbIdsRepository; @@ -83,6 +85,7 @@ public class PersistComponentsStep implements ComputationStep { this.disabledComponentsHolder = disabledComponentsHolder; this.analysisMetadataHolder = analysisMetadataHolder; this.branchPersister = branchPersister; + this.projectPersister = projectPersister; } @Override @@ -94,6 +97,7 @@ public class PersistComponentsStep implements ComputationStep { public void execute(ComputationStep.Context context) { try (DbSession dbSession = dbClient.openSession(false)) { branchPersister.persist(dbSession); + projectPersister.persist(dbSession); String projectUuid = treeRootHolder.getRoot().getUuid(); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java index 730f0324343..4359d0d8950 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/BranchPersisterImplTest.java @@ -105,7 +105,7 @@ public class BranchPersisterImplTest { // add project and branch in table PROJECTS ComponentDto mainComponent = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getKey()); - ComponentDto component = ComponentTesting.newProjectBranch(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH)); + ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH)); dbTester.getDbClient().componentDao().insert(dbTester.getSession(), mainComponent, component); dbTester.commit(); // set project in metadata @@ -117,7 +117,7 @@ public class BranchPersisterImplTest { dbTester.getSession().commit(); - assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(2); + assertThat(dbTester.countRowsOfTable("components")).isEqualTo(2); Optional branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH1.getUuid()); assertThat(branchDto).isPresent(); assertThat(branchDto.get().getBranchType()).isEqualTo(BRANCH); @@ -131,7 +131,7 @@ public class BranchPersisterImplTest { public void main_branch_is_excluded_from_branch_purge_by_default() { analysisMetadataHolder.setBranch(createBranch(BRANCH, true, "master")); treeRootHolder.setRoot(MAIN); - dbTester.components().insertMainBranch(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid())); + dbTester.components().insertPublicProject(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid())); dbTester.commit(); underTest.persist(dbTester.getSession()); @@ -146,8 +146,8 @@ public class BranchPersisterImplTest { analysisMetadataHolder.setBranch(createBranch(BRANCH, false, "BRANCH_KEY")); treeRootHolder.setRoot(BRANCH1); - ComponentDto mainComponent = dbTester.components().insertMainBranch(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid())); - ComponentDto component = ComponentTesting.newProjectBranch(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH)); + ComponentDto mainComponent = dbTester.components().insertPublicProject(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid())); + ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH)); dbTester.getDbClient().componentDao().insert(dbTester.getSession(), component); dbTester.commit(); @@ -163,8 +163,8 @@ public class BranchPersisterImplTest { analysisMetadataHolder.setBranch(createBranch(BRANCH, false, "BRANCH_KEY")); treeRootHolder.setRoot(BRANCH1); - ComponentDto mainComponent = dbTester.components().insertMainBranch(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid())); - ComponentDto component = ComponentTesting.newProjectBranch(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH)); + ComponentDto mainComponent = dbTester.components().insertPublicProject(p -> p.setDbKey(MAIN.getDbKey()).setUuid(MAIN.getUuid())); + ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(BRANCH)); dbTester.getDbClient().componentDao().insert(dbTester.getSession(), component); dbTester.commit(); @@ -188,7 +188,7 @@ public class BranchPersisterImplTest { // add project and branch in table PROJECTS ComponentDto mainComponent = ComponentTesting.newPrivateProjectDto(dbTester.organizations().insert(), MAIN.getUuid()).setDbKey(MAIN.getKey()); - ComponentDto component = ComponentTesting.newProjectBranch(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(PULL_REQUEST)); + ComponentDto component = ComponentTesting.newBranchComponent(mainComponent, new BranchDto().setUuid(BRANCH1.getUuid()).setKey(BRANCH1.getKey()).setBranchType(PULL_REQUEST)); dbTester.getDbClient().componentDao().insert(dbTester.getSession(), mainComponent, component); dbTester.commit(); // set project in metadata @@ -201,7 +201,7 @@ public class BranchPersisterImplTest { dbTester.getSession().commit(); - assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(2); + assertThat(dbTester.countRowsOfTable("components")).isEqualTo(2); Optional branchDto = dbTester.getDbClient().branchDao().selectByUuid(dbTester.getSession(), BRANCH1.getUuid()); assertThat(branchDto).isPresent(); assertThat(branchDto.get().getBranchType()).isEqualTo(PULL_REQUEST); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryTest.java index b40925e9e88..6c8b5144e8c 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryTest.java @@ -121,7 +121,7 @@ public class ConfigurationRepositoryTest { @Test public void branch_settings() { - ComponentDto project = db.components().insertMainBranch(); + ComponentDto project = db.components().insertPublicProject(); ComponentDto branchDto = db.components().insertProjectBranch(project); Branch branch = mock(Branch.class); when(branch.getName()).thenReturn(branchDto.getBranch()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ProjectPersisterTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ProjectPersisterTest.java new file mode 100644 index 00000000000..af89af4648a --- /dev/null +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ProjectPersisterTest.java @@ -0,0 +1,115 @@ +/* + * 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.component; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.impl.utils.TestSystem2; +import org.sonar.api.utils.System2; +import org.sonar.ce.task.projectanalysis.analysis.AnalysisMetadataHolderRule; +import org.sonar.db.DbTester; +import org.sonar.db.project.ProjectDto; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.PROJECT; +import static org.sonar.ce.task.projectanalysis.component.Component.Type.VIEW; +import static org.sonar.ce.task.projectanalysis.component.ReportComponent.builder; + +public class ProjectPersisterTest { + private final static Component ROOT = builder(PROJECT, 1) + .setUuid("PROJECT_UUID") + .setKey("PROJECT_KEY") + .setDescription("PROJECT_DESC") + .setName("PROJECT_NAME") + .build(); + + @Rule + public AnalysisMetadataHolderRule analysisMetadataHolder = new AnalysisMetadataHolderRule(); + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); + @Rule + public TreeRootHolderRule treeRootHolder = new TreeRootHolderRule(); + @Rule + public ExpectedException exception = ExpectedException.none(); + public TestSystem2 system2 = new TestSystem2(); + + private ProjectPersister underTest = new ProjectPersister(dbTester.getDbClient(), treeRootHolder, system2); + + @Before + public void prepare() { + treeRootHolder.setRoot(ROOT); + system2.setNow(1000L); + } + + @Test + public void skip_portfolios() { + Component root = ViewsComponent.builder(VIEW, 1).build(); + TreeRootHolder treeRootHolder = mock(TreeRootHolder.class); + when(treeRootHolder.getRoot()).thenReturn(root); + new ProjectPersister(dbTester.getDbClient(), treeRootHolder, system2).persist(dbTester.getSession()); + verify(treeRootHolder).getRoot(); + verifyNoMoreInteractions(treeRootHolder); + + } + + @Test + public void update_description() { + ProjectDto p1 = dbTester.components().insertPublicProjectDto(dbTester.getDefaultOrganization(), + c -> c.setUuid("PROJECT_UUID").setDbKey(ROOT.getKey()).setName(ROOT.getName()).setDescription("OLD_DESC")); + + assertProject("OLD_DESC", ROOT.getName(), p1.getUpdatedAt()); + underTest.persist(dbTester.getSession()); + assertProject(ROOT.getDescription(), ROOT.getName(), 1000L); + } + + @Test + public void update_name() { + ProjectDto p1 = dbTester.components().insertPublicProjectDto(dbTester.getDefaultOrganization(), + c -> c.setUuid("PROJECT_UUID").setDbKey(ROOT.getKey()).setName("OLD_NAME").setDescription(ROOT.getDescription())); + + assertProject(ROOT.getDescription(), "OLD_NAME", p1.getUpdatedAt()); + underTest.persist(dbTester.getSession()); + assertProject(ROOT.getDescription(), ROOT.getName(), 1000L); + } + + @Test + public void dont_update() { + ProjectDto p1 = dbTester.components().insertPublicProjectDto(dbTester.getDefaultOrganization(), + c -> c.setUuid("PROJECT_UUID").setDbKey(ROOT.getKey()).setName(ROOT.getName()).setDescription(ROOT.getDescription())); + + assertProject(ROOT.getDescription(), ROOT.getName(), p1.getUpdatedAt()); + underTest.persist(dbTester.getSession()); + assertProject(ROOT.getDescription(), ROOT.getName(), p1.getUpdatedAt()); + } + + private void assertProject(String description, String name, long updated) { + assertThat(dbTester.getDbClient().projectDao().selectProjectByKey(dbTester.getSession(), ROOT.getKey()).get()) + .extracting(ProjectDto::getName, ProjectDto::getDescription, ProjectDto::getUpdatedAt) + .containsExactly(name, description, updated); + + } +} diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuidsTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuidsTest.java index 7f04822a3d2..dd4b8d83478 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuidsTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/ReferenceBranchComponentUuidsTest.java @@ -62,7 +62,7 @@ public class ReferenceBranchComponentUuidsTest { analysisMetadataHolder.setProject(project); analysisMetadataHolder.setBranch(branch); - ComponentDto projectDto = db.components().insertMainBranch(); + ComponentDto projectDto = db.components().insertPublicProject(); when(project.getUuid()).thenReturn(projectDto.uuid()); branch1 = db.components().insertProjectBranch(projectDto, b -> b.setKey("branch1")); branch2 = db.components().insertProjectBranch(projectDto, b -> b.setKey("branch2")); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssuesTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssuesTest.java index 6079985d17a..bce2e086cd8 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssuesTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/component/SiblingComponentsWithOpenIssuesTest.java @@ -63,7 +63,7 @@ public class SiblingComponentsWithOpenIssuesTest { @Before public void setUp() { - ComponentDto project = db.components().insertMainBranch(); + ComponentDto project = db.components().insertPublicProject(); branch1 = db.components().insertProjectBranch(project, b -> b.setKey("branch1"), b -> b.setBranchType(BranchType.BRANCH)); branch1pr1 = db.components().insertProjectBranch(project, @@ -157,7 +157,7 @@ public class SiblingComponentsWithOpenIssuesTest { @Test public void should_find_sibling_components_with_open_issues_from_pullrequest() { - ComponentDto project = db.components().insertMainBranch(); + ComponentDto project = db.components().insertPublicProject(); setRoot(project); setBranch(BranchType.BRANCH); @@ -176,7 +176,7 @@ public class SiblingComponentsWithOpenIssuesTest { @Test public void should_not_find_sibling_components_on_derived_branch() { - ComponentDto project = db.components().insertMainBranch(); + ComponentDto project = db.components().insertPublicProject(); setRoot(project); setBranch(BranchType.BRANCH); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ProjectTrackerBaseLazyInputTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ProjectTrackerBaseLazyInputTest.java index f6f23259141..740c4f0f592 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ProjectTrackerBaseLazyInputTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/ProjectTrackerBaseLazyInputTest.java @@ -74,7 +74,7 @@ public class ProjectTrackerBaseLazyInputTest { public void prepare() { rule = dbTester.rules().insert(); ruleRepositoryRule.add(rule.getKey()); - rootProjectDto = dbTester.components().insertMainBranch(); + rootProjectDto = dbTester.components().insertPublicProject(); ReportComponent rootProject = ReportComponent.builder(Component.Type.FILE, 1) .setKey(rootProjectDto.getDbKey()) .setUuid(rootProjectDto.uuid()).build(); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java index 3d0ac23eda5..5df924d9aa7 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/issue/SiblingsIssueMergerTest.java @@ -109,7 +109,7 @@ public class SiblingsIssueMergerTest { copier = new SiblingsIssueMerger(new SiblingsIssuesLoader(new SiblingComponentsWithOpenIssues(treeRootHolder, metadataHolder, dbClient), dbClient, componentIssuesLoader), tracker, issueLifecycle); - projectDto = db.components().insertMainBranch(p -> p.setDbKey(PROJECT_KEY).setUuid(PROJECT_UUID)); + projectDto = db.components().insertPublicProject(p -> p.setDbKey(PROJECT_KEY).setUuid(PROJECT_UUID)); branch1Dto = db.components().insertProjectBranch(projectDto, b -> b.setKey("myBranch1") .setBranchType(BranchType.PULL_REQUEST) .setMergeBranchUuid(projectDto.uuid())); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java index 148aaa2f448..3c5307a120a 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/BuildComponentTreeStepTest.java @@ -196,7 +196,7 @@ public class BuildComponentTreeStepTest { @Test public void generate_keys_when_using_existing_branch() { - ComponentDto projectDto = dbTester.components().insertMainBranch(); + ComponentDto projectDto = dbTester.components().insertPublicProject(); ComponentDto branchDto = dbTester.components().insertProjectBranch(projectDto); Branch branch = mock(Branch.class); when(branch.getName()).thenReturn(branchDto.getBranch()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadPeriodsStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadPeriodsStepTest.java index 104674857b0..b58ffb3c481 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadPeriodsStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/LoadPeriodsStepTest.java @@ -103,7 +103,7 @@ public class LoadPeriodsStepTest extends BaseStepTest { @Before public void setUp() { organization = dbTester.organizations().insert(); - project = dbTester.components().insertMainBranch(organization); + project = dbTester.components().insertPublicProject(organization); when(analysisMetadataHolder.isBranch()).thenReturn(true); when(analysisMetadataHolder.isFirstAnalysis()).thenReturn(false); @@ -241,7 +241,7 @@ public class LoadPeriodsStepTest extends BaseStepTest { @Test public void throw_ISE_when_specific_analysis_is_set_but_does_not_exist_in_DB() { OrganizationDto organization = dbTester.organizations().insert(); - ComponentDto project = dbTester.components().insertMainBranch(organization); + ComponentDto project = dbTester.components().insertPublicProject(organization); setProjectPeriod(project.uuid(), NewCodePeriodType.SPECIFIC_ANALYSIS, "nonexistent"); setupRoot(project); @@ -253,7 +253,7 @@ public class LoadPeriodsStepTest extends BaseStepTest { @Test public void throw_ISE_when_specific_analysis_is_set_but_does_not_belong_to_current_project() { - ComponentDto otherProject = dbTester.components().insertMainBranch(organization); + ComponentDto otherProject = dbTester.components().insertPublicProject(organization); SnapshotDto otherProjectAnalysis = dbTester.components().insertSnapshot(otherProject); setBranchPeriod(project.uuid(), project.uuid(), NewCodePeriodType.SPECIFIC_ANALYSIS, otherProjectAnalysis.getUuid()); setupRoot(project); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStepTest.java index 905d47fb769..d4da264cdc2 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/PersistComponentsStepTest.java @@ -28,6 +28,7 @@ import org.sonar.ce.task.projectanalysis.component.BranchPersister; import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.MutableDbIdsRepository; import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder; +import org.sonar.ce.task.projectanalysis.component.ProjectPersister; import org.sonar.ce.task.projectanalysis.component.TreeRootHolder; import org.sonar.ce.task.step.TestComputationStepContext; import org.sonar.db.DbClient; @@ -69,6 +70,7 @@ public class PersistComponentsStepTest { System2.INSTANCE, mock(MutableDisabledComponentsHolder.class), mock(AnalysisMetadataHolder.class), - mock(BranchPersister.class)).execute(new TestComputationStepContext()); + mock(BranchPersister.class), + mock(ProjectPersister.class)).execute(new TestComputationStepContext()); } } diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java index e666a663eae..71f2cbcf44a 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ReportPersistComponentsStepTest.java @@ -38,6 +38,7 @@ import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl; import org.sonar.ce.task.projectanalysis.component.FileAttributes; import org.sonar.ce.task.projectanalysis.component.MutableDbIdsRepositoryRule; import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder; +import org.sonar.ce.task.projectanalysis.component.ProjectPersister; import org.sonar.ce.task.projectanalysis.component.ReportComponent; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; import org.sonar.ce.task.step.ComputationStep; @@ -95,7 +96,8 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { db.organizations().insertForUuid(ORGANIZATION_UUID); BranchPersister branchPersister = mock(BranchPersister.class); - underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister); + ProjectPersister projectPersister = mock(ProjectPersister.class); + underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister, projectPersister); } @Override @@ -123,7 +125,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(db.countRowsOfTable("projects")).isEqualTo(3); + assertThat(db.countRowsOfTable("components")).isEqualTo(3); ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get(); assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); @@ -185,7 +187,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(db.countRowsOfTable("projects")).isEqualTo(3); + assertThat(db.countRowsOfTable("components")).isEqualTo(3); ComponentDto directoryDto = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get(); assertThat(directoryDto.getOrganizationUuid()).isEqualTo(ORGANIZATION_UUID); @@ -365,7 +367,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(db.countRowsOfTable("projects")).isEqualTo(3); + assertThat(db.countRowsOfTable("components")).isEqualTo(3); ComponentDto projectReloaded = dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get(); assertThat(projectReloaded.getId()).isEqualTo(project.getId()); @@ -414,7 +416,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(db.countRowsOfTable("projects")).isEqualTo(3); + assertThat(db.countRowsOfTable("components")).isEqualTo(3); assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().getId()).isEqualTo(project.getId()); assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get().getId()).isEqualTo(directory.getId()); assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(file.getId()); @@ -476,7 +478,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { dbClient.componentDao().applyBChangesForRootComponentUuid(db.getSession(), project.uuid()); db.commit(); - assertThat(db.countRowsOfTable("projects")).isEqualTo(3); + assertThat(db.countRowsOfTable("components")).isEqualTo(3); ComponentDto directoryReloaded = dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get(); assertThat(directoryReloaded).isNotNull(); @@ -548,7 +550,7 @@ public class ReportPersistComponentsStepTest extends BaseStepTest { underTest.execute(new TestComputationStepContext()); - assertThat(db.countRowsOfTable("projects")).isEqualTo(3); + assertThat(db.countRowsOfTable("components")).isEqualTo(3); assertThat(dbClient.componentDao().selectByKey(db.getSession(), project.getDbKey()).get().getId()).isEqualTo(project.getId()); assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir").get().getId()).isEqualTo(removedDirectory.getId()); assertThat(dbClient.componentDao().selectByKey(db.getSession(), "PROJECT_KEY:src/main/java/dir/Foo.java").get().getId()).isEqualTo(removedFile.getId()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepTest.java index 2c34348cc4f..11be48ed072 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/SendIssueNotificationsStepTest.java @@ -101,7 +101,7 @@ import static org.sonar.db.component.BranchType.PULL_REQUEST; import static org.sonar.db.component.ComponentTesting.newBranchDto; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto; -import static org.sonar.db.component.ComponentTesting.newProjectBranch; +import static org.sonar.db.component.ComponentTesting.newBranchComponent; import static org.sonar.db.issue.IssueTesting.newIssue; import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto; import static org.sonar.db.rule.RuleTesting.newRule; @@ -560,7 +560,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest { private void sendIssueChangeNotificationOnBranch(long issueCreatedAt) { ComponentDto project = newPrivateProjectDto(newOrganizationDto()); - ComponentDto branch = newProjectBranch(project, newBranchDto(project).setKey(BRANCH_NAME)); + ComponentDto branch = newBranchComponent(project, newBranchDto(project).setKey(BRANCH_NAME)); ComponentDto file = newFileDto(branch); treeRootHolder.setRoot(builder(Type.PROJECT, 2).setKey(branch.getDbKey()).setPublicKey(branch.getKey()).setName(branch.longName()).setUuid(branch.uuid()).addChildren( builder(Type.FILE, 11).setKey(file.getDbKey()).setPublicKey(file.getKey()).setName(file.longName()).build()).build()); @@ -692,7 +692,7 @@ public class SendIssueNotificationsStepTest extends BaseStepTest { } private ComponentDto setUpBranch(ComponentDto project, BranchType branchType) { - ComponentDto branch = newProjectBranch(project, newBranchDto(project, branchType).setKey(BRANCH_NAME)); + ComponentDto branch = newBranchComponent(project, newBranchDto(project, branchType).setKey(BRANCH_NAME)); ComponentDto file = newFileDto(branch); treeRootHolder.setRoot(builder(Type.PROJECT, 2).setKey(branch.getDbKey()).setPublicKey(branch.getKey()).setName(branch.longName()).setUuid(branch.uuid()).addChildren( builder(Type.FILE, 11).setKey(file.getDbKey()).setPublicKey(file.getKey()).setName(file.longName()).build()).build()); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java index f6ede0e98a1..42a52d6d3a5 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ValidateProjectStepTest.java @@ -69,7 +69,7 @@ public class ValidateProjectStepTest { @Test public void fail_if_pr_is_targeting_branch_with_modules() { - ComponentDto masterProject = dbTester.components().insertMainBranch(); + ComponentDto masterProject = dbTester.components().insertPublicProject(); ComponentDto mergeBranch = dbTester.components().insertProjectBranch(masterProject, b -> b.setKey("mergeBranch")); dbClient.componentDao().insert(dbTester.getSession(), ComponentTesting.newModuleDto(mergeBranch)); setBranch(BranchType.PULL_REQUEST, mergeBranch.uuid()); @@ -86,7 +86,7 @@ public class ValidateProjectStepTest { @Test public void dont_fail_for_long_forked_from_master_with_modules() { - ComponentDto masterProject = dbTester.components().insertMainBranch(); + ComponentDto masterProject = dbTester.components().insertPublicProject(); dbClient.componentDao().insert(dbTester.getSession(), ComponentTesting.newModuleDto(masterProject)); setBranch(BranchType.BRANCH, masterProject.uuid()); dbTester.getSession().commit(); diff --git a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsPersistComponentsStepTest.java b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsPersistComponentsStepTest.java index 11e583ccc27..fe5c7f40f8e 100644 --- a/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsPersistComponentsStepTest.java +++ b/server/sonar-ce-task-projectanalysis/src/test/java/org/sonar/ce/task/projectanalysis/step/ViewsPersistComponentsStepTest.java @@ -36,6 +36,7 @@ import org.sonar.ce.task.projectanalysis.component.Component; import org.sonar.ce.task.projectanalysis.component.DefaultBranchImpl; import org.sonar.ce.task.projectanalysis.component.MutableDbIdsRepositoryRule; import org.sonar.ce.task.projectanalysis.component.MutableDisabledComponentsHolder; +import org.sonar.ce.task.projectanalysis.component.ProjectPersister; import org.sonar.ce.task.projectanalysis.component.ProjectViewAttributes; import org.sonar.ce.task.projectanalysis.component.SubViewAttributes; import org.sonar.ce.task.projectanalysis.component.TreeRootHolderRule; @@ -104,7 +105,8 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { dbTester.organizations().insertForUuid(ORGANIZATION_UUID); analysisMetadataHolder.setBranch(new DefaultBranchImpl()); BranchPersister branchPersister = mock(BranchPersister.class); - underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister); + ProjectPersister projectPersister = mock(ProjectPersister.class); + underTest = new PersistComponentsStep(dbClient, treeRootHolder, dbIdsRepository, system2, disabledComponentsHolder, analysisMetadataHolder, branchPersister, projectPersister); } @Override @@ -482,7 +484,7 @@ public class ViewsPersistComponentsStepTest extends BaseStepTest { } private void assertRowsCountInTableProjects(int rowCount) { - assertThat(dbTester.countRowsOfTable("projects")).isEqualTo(rowCount); + assertThat(dbTester.countRowsOfTable("components")).isEqualTo(rowCount); } private void assertDtoNotUpdated(String componentKey) { diff --git a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java index b99e0c4b47d..4a62219ab11 100644 --- a/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java +++ b/server/sonar-ce/src/test/java/org/sonar/ce/container/ComputeEngineContainerImplTest.java @@ -128,7 +128,7 @@ public class ComputeEngineContainerImplTest { assertThat(picoContainer.getParent().getParent().getParent().getComponentAdapters()).hasSize( COMPONENTS_IN_LEVEL_1_AT_CONSTRUCTION + 27 // level 1 - + 65 // content of DaoModule + + 66 // content of DaoModule + 3 // content of EsModule + 50 // content of CorePropertyDefinitions + 1 // StopFlagContainer diff --git a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java index d401aa0ec46..1cc30304e5d 100644 --- a/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java +++ b/server/sonar-db-core/src/main/java/org/sonar/db/version/SqTables.java @@ -61,6 +61,7 @@ public final class SqTables { "ce_task_input", "ce_task_message", "ce_scanner_context", + "components", "default_qprofiles", "deprecated_rule_keys", "duplications_index", diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java index 34f8d4e0d37..9cf5de73ba4 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DaoModule.java @@ -61,6 +61,7 @@ import org.sonar.db.permission.UserPermissionDao; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDao; import org.sonar.db.permission.template.PermissionTemplateDao; import org.sonar.db.plugin.PluginDao; +import org.sonar.db.project.ProjectDao; import org.sonar.db.property.InternalComponentPropertiesDao; import org.sonar.db.property.InternalPropertiesDao; import org.sonar.db.property.PropertiesDao; @@ -135,6 +136,7 @@ public class DaoModule extends Module { PermissionTemplateCharacteristicDao.class, PermissionTemplateDao.class, PluginDao.class, + ProjectDao.class, ProjectLinkDao.class, ProjectMappingsDao.class, ProjectQgateAssociationDao.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java index c7a3bea3ce1..9707a025944 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/DbClient.java @@ -59,6 +59,7 @@ import org.sonar.db.permission.UserPermissionDao; import org.sonar.db.permission.template.PermissionTemplateCharacteristicDao; import org.sonar.db.permission.template.PermissionTemplateDao; import org.sonar.db.plugin.PluginDao; +import org.sonar.db.project.ProjectDao; import org.sonar.db.property.InternalComponentPropertiesDao; import org.sonar.db.property.InternalPropertiesDao; import org.sonar.db.property.PropertiesDao; @@ -158,6 +159,7 @@ public class DbClient { private final ProjectMappingsDao projectMappingsDao; private final OrganizationAlmBindingDao organizationAlmBindingDao; private final NewCodePeriodDao newCodePeriodDao; + private final ProjectDao projectDao; public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { this.database = database; @@ -233,6 +235,7 @@ public class DbClient { organizationAlmBindingDao = getDao(map, OrganizationAlmBindingDao.class); internalComponentPropertiesDao = getDao(map, InternalComponentPropertiesDao.class); newCodePeriodDao = getDao(map, NewCodePeriodDao.class); + projectDao = getDao(map, ProjectDao.class); } public DbSession openSession(boolean batch) { @@ -311,6 +314,10 @@ public class DbClient { return componentDao; } + public ProjectDao projectDao() { + return projectDao; + } + public ComponentKeyUpdaterDao componentKeyUpdaterDao() { return componentKeyUpdaterDao; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java index 53cd1122e1c..0fc20ca8a47 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/MyBatis.java @@ -102,6 +102,8 @@ import org.sonar.db.permission.template.PermissionTemplateMapper; import org.sonar.db.permission.template.PermissionTemplateUserDto; import org.sonar.db.plugin.PluginDto; import org.sonar.db.plugin.PluginMapper; +import org.sonar.db.project.ProjectDto; +import org.sonar.db.project.ProjectMapper; import org.sonar.db.property.InternalComponentPropertiesMapper; import org.sonar.db.property.InternalComponentPropertyDto; import org.sonar.db.property.InternalPropertiesMapper; @@ -202,6 +204,7 @@ public class MyBatis implements Startable { confBuilder.loadAlias("PrIssue", PrIssueDto.class); confBuilder.loadAlias("ProjectAlmBinding", ProjectAlmBindingDto.class); confBuilder.loadAlias("ProjectQgateAssociation", ProjectQgateAssociationDto.class); + confBuilder.loadAlias("Project", ProjectDto.class); confBuilder.loadAlias("ProjectMapping", ProjectMappingDto.class); confBuilder.loadAlias("PurgeableAnalysis", PurgeableAnalysisDto.class); confBuilder.loadAlias("QualityGateCondition", QualityGateConditionDto.class); @@ -267,6 +270,7 @@ public class MyBatis implements Startable { ProjectAlmBindingMapper.class, ProjectAlmSettingMapper.class, ProjectLinkMapper.class, + ProjectMapper.class, ProjectMappingsMapper.class, ProjectQgateAssociationMapper.class, PropertiesMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDao.java index 7d73d4c341c..7e67ce74e70 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/alm/setting/ProjectAlmSettingDao.java @@ -25,6 +25,7 @@ import org.sonar.core.util.UuidFactory; import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; +import org.sonar.db.project.ProjectDto; public class ProjectAlmSettingDao implements Dao { @@ -49,8 +50,8 @@ public class ProjectAlmSettingDao implements Dao { projectAlmSettingDto.setUpdatedAt(now); } - public void deleteByProject(DbSession dbSession, ComponentDto project) { - getMapper(dbSession).deleteByProjectUuid(project.uuid()); + public void deleteByProject(DbSession dbSession, ProjectDto project) { + getMapper(dbSession).deleteByProjectUuid(project.getUuid()); } public void deleteByAlmSetting(DbSession dbSession, AlmSettingDto almSetting) { @@ -61,8 +62,8 @@ public class ProjectAlmSettingDao implements Dao { return getMapper(dbSession).countByAlmSettingUuid(almSetting.getUuid()); } - public Optional selectByProject(DbSession dbSession, ComponentDto project) { - return selectByProject(dbSession, project.uuid()); + public Optional selectByProject(DbSession dbSession, ProjectDto project) { + return selectByProject(dbSession, project.getUuid()); } public Optional selectByProject(DbSession dbSession, String projectUuid) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java index 434e04f1b51..bc116be2d0b 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchDao.java @@ -20,11 +20,14 @@ package org.sonar.db.component; import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Map; import java.util.Optional; import org.sonar.api.utils.System2; import org.sonar.db.Dao; import org.sonar.db.DbSession; +import org.sonar.db.project.ProjectDto; import static org.sonar.db.DatabaseUtils.executeLargeInputs; @@ -72,6 +75,13 @@ public class BranchDao implements Dao { return selectByKey(dbSession, projectUuid, key, KeyType.BRANCH); } + public List selectByBranchKeys(DbSession dbSession, Map branchKeyByProjectUuid) { + if (branchKeyByProjectUuid.isEmpty()) { + return Collections.emptyList(); + } + return mapper(dbSession).selectByBranchKeys(branchKeyByProjectUuid); + } + public Optional selectByPullRequestKey(DbSession dbSession, String projectUuid, String key) { return selectByKey(dbSession, projectUuid, key, KeyType.PULL_REQUEST); } @@ -88,6 +98,10 @@ public class BranchDao implements Dao { return mapper(dbSession).selectByProjectUuid(projectUuid); } + public Collection selectByProject(DbSession dbSession, ProjectDto project) { + return mapper(dbSession).selectByProjectUuid(project.getUuid()); + } + public List selectByUuids(DbSession session, Collection uuids) { return executeLargeInputs(uuids, mapper(session)::selectByUuids); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java index 997d3a59516..fc7987f4572 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/BranchMapper.java @@ -21,8 +21,10 @@ package org.sonar.db.component; import java.util.Collection; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; import org.apache.ibatis.annotations.Param; +import org.sonar.db.DbSession; public interface BranchMapper { @@ -43,6 +45,8 @@ public interface BranchMapper { Collection selectByProjectUuid(@Param("projectUuid") String projectUuid); + List selectByBranchKeys(@Param("branchKeyByProjectUuid") Map branchKeyByProjectUuid); + List selectByUuids(@Param("uuids") Collection uuids); long countNonMainBranches(); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java index 710ef904c0f..54f0ba7b0df 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java @@ -73,14 +73,6 @@ public class ComponentDao implements Dao { return mapper(session).countByQuery(organizationUuid, query); } - @CheckForNull - private static String buildUpperLikeSql(@Nullable String textQuery) { - if (isBlank(textQuery)) { - return null; - } - return buildLikeValue(textQuery.toUpperCase(Locale.ENGLISH), BEFORE_AND_AFTER); - } - private static ComponentMapper mapper(DbSession session) { return session.getMapper(ComponentMapper.class); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java index 10495b676b6..61dcb2242b6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterDao.java @@ -20,7 +20,6 @@ package org.sonar.db.component; import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import java.util.Collection; import java.util.HashMap; @@ -36,10 +35,10 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.sonar.api.resources.Qualifiers; +import org.sonar.api.resources.Scopes; import org.sonar.db.Dao; import org.sonar.db.DbSession; -import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.component.ComponentKeys.checkProjectKey; /** @@ -48,25 +47,21 @@ import static org.sonar.core.component.ComponentKeys.checkProjectKey; * @since 3.2 */ public class ComponentKeyUpdaterDao implements Dao { - - private static final Set PROJECT_OR_MODULE_QUALIFIERS = ImmutableSet.of(Qualifiers.PROJECT, Qualifiers.MODULE); - - public void updateKey(DbSession dbSession, String projectOrModuleUuid, String newKey) { + public void updateKey(DbSession dbSession, String projectUuid, String newKey) { ComponentKeyUpdaterMapper mapper = dbSession.getMapper(ComponentKeyUpdaterMapper.class); if (mapper.countResourceByKey(newKey) > 0) { throw new IllegalArgumentException("Impossible to update key: a component with key \"" + newKey + "\" already exists."); } // must SELECT first everything - ResourceDto project = mapper.selectProjectByUuid(projectOrModuleUuid); + ResourceDto project = mapper.selectProjectByUuid(projectUuid); String projectOldKey = project.getKey(); - List resources = mapper.selectProjectResources(projectOrModuleUuid); + List resources = mapper.selectProjectResources(projectUuid); resources.add(project); // add branch components - dbSession.getMapper(BranchMapper.class).selectByProjectUuid(projectOrModuleUuid) - .stream() - .filter(branch -> !projectOrModuleUuid.equals(branch.getUuid())) + dbSession.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid).stream() + .filter(branch -> !projectUuid.equals(branch.getUuid())) .forEach(branch -> { resources.addAll(mapper.selectProjectResources(branch.getUuid())); resources.add(mapper.selectProjectByUuid(branch.getUuid())); @@ -77,10 +72,6 @@ public class ComponentKeyUpdaterDao implements Dao { }); } - public static void checkIsProjectOrModule(ComponentDto component) { - checkArgument(PROJECT_OR_MODULE_QUALIFIERS.contains(component.qualifier()), "Component updated must be a module or a key"); - } - /** * * @return a map with currentKey/newKey is a bulk update was executed @@ -118,8 +109,7 @@ public class ComponentKeyUpdaterDao implements Dao { // add branches (no check should be done as branch keys cannot be changed by the user) Map branchBaseKeys = new HashMap<>(); - session.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid) - .stream() + session.getMapper(BranchMapper.class).selectByProjectUuid(projectUuid).stream() .filter(branch -> !projectUuid.equals(branch.getUuid())) .forEach(branch -> { Set branchModules = collectAllModules(branch.getUuid(), stringToReplace, mapper, true); @@ -167,14 +157,18 @@ public class ComponentKeyUpdaterDao implements Dao { @Nullable BiConsumer consumer) { for (ResourceDto resource : resources) { String oldResourceKey = resource.getKey(); - String newResourceKey = newKey + oldResourceKey.substring(oldKey.length(), oldResourceKey.length()); + String newResourceKey = newKey + oldResourceKey.substring(oldKey.length()); resource.setKey(newResourceKey); String oldResourceDeprecatedKey = resource.getDeprecatedKey(); if (StringUtils.isNotBlank(oldResourceDeprecatedKey)) { - String newResourceDeprecatedKey = newKey + oldResourceDeprecatedKey.substring(oldKey.length(), oldResourceDeprecatedKey.length()); + String newResourceDeprecatedKey = newKey + oldResourceDeprecatedKey.substring(oldKey.length()); resource.setDeprecatedKey(newResourceDeprecatedKey); } - mapper.update(resource); + mapper.updateComponent(resource); + if (resource.getScope().equals(Scopes.PROJECT) && (resource.getQualifier().equals(Qualifiers.PROJECT) || resource.getQualifier().equals(Qualifiers.APP))) { + mapper.updateProject(oldResourceKey, newResourceKey); + } + if (consumer != null) { consumer.accept(resource, oldResourceKey); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java index c5c560db291..64c14ffce0b 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentKeyUpdaterMapper.java @@ -32,6 +32,8 @@ public interface ComponentKeyUpdaterMapper { List selectDescendantProjects(@Param("rootUuid") String rootUuid); - void update(ResourceDto resource); + void updateComponent(ResourceDto resource); + + void updateProject(@Param("oldProjectKey") String oldProjectKey, @Param("newProjectKey") String newProjectKey); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java index c700eef4330..37f74824907 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/issue/IssueTesting.java @@ -29,6 +29,7 @@ import org.sonar.api.utils.DateUtils; import org.sonar.core.util.UuidFactoryFast; import org.sonar.core.util.Uuids; import org.sonar.db.component.ComponentDto; +import org.sonar.db.project.ProjectDto; import org.sonar.db.rule.RuleDefinitionDto; import org.sonar.db.rule.RuleDto; @@ -47,13 +48,22 @@ public class IssueTesting { public static IssueDto newIssue(RuleDefinitionDto rule, ComponentDto project, ComponentDto file) { checkArgument(project.qualifier().equals(Qualifiers.PROJECT), "Second parameter should be a project"); - checkArgument(file.projectUuid().equals(project.uuid()), "The file doesn't belong to the project"); + return newIssue(rule, project.uuid(), project.getDbKey(), file); + } + + public static IssueDto newIssue(RuleDefinitionDto rule, ProjectDto project, ComponentDto file) { + return newIssue(rule, project.getUuid(), project.getKey(), file); + } + + public static IssueDto newIssue(RuleDefinitionDto rule, String projectUuid, String projectKey, ComponentDto file) { + checkArgument(file.projectUuid().equals(projectUuid), "The file doesn't belong to the project"); return new IssueDto() .setKee("uuid_" + randomAlphabetic(5)) .setRule(rule) .setType(RuleType.values()[nextInt(RuleType.values().length)]) - .setProject(project) + .setProjectUuid(projectUuid) + .setProjectKey(projectKey) .setComponent(file) .setStatus(Issue.STATUS_OPEN) .setResolution(null) diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java index 593256b3066..6892169d1b3 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/ProjectMeasuresIndexerIterator.java @@ -69,10 +69,11 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator selectProjectByKey(DbSession session, String key) { + return Optional.ofNullable(mapper(session).selectProjectByKey(key)); + } + + public Optional selectApplicationByKey(DbSession session, String key) { + return Optional.ofNullable(mapper(session).selectApplicationByKey(key)); + } + + public Optional selectProjectOrAppByKey(DbSession session, String key) { + return Optional.ofNullable(mapper(session).selectProjectOrAppByKey(key)); + } + + public List selectProjectsByKeys(DbSession session, Set keys) { + if (keys.isEmpty()) { + return Collections.emptyList(); + } + return mapper(session).selectProjectsByKeys(keys); + } + + public List selectProjects(DbSession session) { + return mapper(session).selectProjects(); + } + + public Optional selectByUuid(DbSession session, String uuid) { + return Optional.ofNullable(mapper(session).selectByUuid(uuid)); + } + + public List selectByOrganizationUuid(DbSession session, String organizationUuid) { + return mapper(session).selectByOrganizationUuid(organizationUuid); + } + + public List selectProjectsByOrganizationUuid(DbSession session, String organizationUuid) { + return mapper(session).selectProjectsByOrganizationUuid(organizationUuid); + } + + public List selectByUuids(DbSession session, Set uuids) { + if (uuids.isEmpty()) { + return Collections.emptyList(); + } + return mapper(session).selectByUuids(uuids); + } + + public void updateTags(DbSession session, ProjectDto project) { + mapper(session).updateTags(project); + } + + public void update(DbSession session, ProjectDto project) { + mapper(session).update(project); + } + + private static ProjectMapper mapper(DbSession session) { + return session.getMapper(ProjectMapper.class); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDto.java new file mode 100644 index 00000000000..e01902c2eb5 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectDto.java @@ -0,0 +1,184 @@ +/* + * 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.db.project; + +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +import static org.apache.commons.lang.StringUtils.trimToNull; +import static org.sonar.db.component.DbTagsReader.readDbTags; + +public class ProjectDto { + private static final String TAGS_SEPARATOR = ","; + private String uuid; + private String kee; + private String qualifier; + private String name; + private String description; + private boolean isPrivate = false; + private String tags; + private long createdAt; + private long updatedAt; + private String organizationUuid; + + public ProjectDto() { + // nothing to do here + } + + public long getCreatedAt() { + return createdAt; + } + + public ProjectDto setCreatedAt(long createdAt) { + this.createdAt = createdAt; + return this; + } + + public long getUpdatedAt() { + return updatedAt; + } + + public ProjectDto setUpdatedAt(long updatedAt) { + this.updatedAt = updatedAt; + return this; + } + + public String getUuid() { + return uuid; + } + + public ProjectDto setUuid(String uuid) { + this.uuid = uuid; + return this; + } + + /** + * This is the getter used by MyBatis mapper. + */ + public String getKee() { + return kee; + } + + public String getKey() { + return getKee(); + } + + /** + * This is the setter used by MyBatis mapper. + */ + public ProjectDto setKee(String kee) { + this.kee = kee; + return this; + } + + public ProjectDto setKey(String key) { + return setKee(key); + } + + public boolean isPrivate() { + return isPrivate; + } + + public ProjectDto setPrivate(boolean aPrivate) { + isPrivate = aPrivate; + return this; + } + + public List getTags() { + return readDbTags(tags); + } + + public ProjectDto setTags(List tags) { + setTagsString(tags.stream() + .filter(t -> !t.isEmpty()) + .collect(Collectors.joining(TAGS_SEPARATOR))); + return this; + } + + /** + * Used by MyBatis + */ + @CheckForNull + public String getTagsString() { + return tags; + } + + public ProjectDto setTagsString(@Nullable String tags) { + this.tags = trimToNull(tags); + return this; + } + + public String getOrganizationUuid() { + return organizationUuid; + } + + public ProjectDto setOrganizationUuid(String organizationUuid) { + this.organizationUuid = organizationUuid; + return this; + } + + public String getName() { + return name; + } + + public ProjectDto setName(String name) { + this.name = name; + return this; + } + + @CheckForNull + public String getDescription() { + return description; + } + + public ProjectDto setDescription(@Nullable String description) { + this.description = description; + return this; + } + + public String getQualifier() { + return qualifier; + } + + public ProjectDto setQualifier(String qualifier) { + this.qualifier = qualifier; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + ProjectDto that = (ProjectDto) o; + return Objects.equals(uuid, that.uuid); + } + + @Override + public int hashCode() { + return uuid != null ? uuid.hashCode() : 0; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.java new file mode 100644 index 00000000000..754358ff2fe --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectMapper.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.db.project; + +import java.util.Collection; +import java.util.List; +import javax.annotation.CheckForNull; +import org.apache.ibatis.annotations.Param; + +public interface ProjectMapper { + + void insert(ProjectDto project); + + @CheckForNull + ProjectDto selectProjectByKey(String key); + + @CheckForNull + ProjectDto selectApplicationByKey(String key); + + @CheckForNull + ProjectDto selectProjectOrAppByKey(String key); + + List selectProjectsByKeys(@Param("kees") Collection kees); + + @CheckForNull + ProjectDto selectByUuid(String uuid); + + List selectByUuids(@Param("uuids") Collection uuids); + + List selectByOrganizationUuid(String organizationUuid); + + void updateTags(ProjectDto project); + + void update(ProjectDto project); + + List selectProjects(); + + List selectProjectsByOrganizationUuid(String organizationUuid); +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectQuery.java new file mode 100644 index 00000000000..266191ec81f --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/ProjectQuery.java @@ -0,0 +1,201 @@ +/* + * 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.db.project; + +import java.util.Date; +import java.util.Locale; +import java.util.Set; +import java.util.stream.Stream; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.sonar.db.WildcardPosition; + +import static com.google.common.base.Preconditions.checkArgument; +import static org.sonar.db.DaoUtils.buildLikeValue; + +public class ProjectQuery { + private final String nameOrKeyQuery; + private final boolean partialMatchOnKey; + private final Boolean isPrivate; + private final Set projectUuids; + private final Set projectKeys; + private final Long analyzedBefore; + private final Long anyBranchAnalyzedBefore; + private final Long anyBranchAnalyzedAfter; + private final Date createdAfter; + private final boolean onProvisionedOnly; + + private ProjectQuery(ProjectQuery.Builder builder) { + this.nameOrKeyQuery = builder.nameOrKeyQuery; + this.partialMatchOnKey = builder.partialMatchOnKey != null && builder.partialMatchOnKey; + this.projectUuids = builder.projectUuids; + this.projectKeys = builder.projectKeys; + this.isPrivate = builder.isPrivate; + this.analyzedBefore = builder.analyzedBefore; + this.anyBranchAnalyzedBefore = builder.anyBranchAnalyzedBefore; + this.anyBranchAnalyzedAfter = builder.anyBranchAnalyzedAfter; + this.createdAfter = builder.createdAfter; + this.onProvisionedOnly = builder.onProvisionedOnly; + } + + @CheckForNull + public String getNameOrKeyQuery() { + return nameOrKeyQuery; + } + + /** + * Used by MyBatis mapper + */ + @CheckForNull + public String getNameOrKeyUpperLikeQuery() { + return buildLikeValue(nameOrKeyQuery, WildcardPosition.BEFORE_AND_AFTER).toUpperCase(Locale.ENGLISH); + } + + /** + * Used by MyBatis mapper + */ + public boolean isPartialMatchOnKey() { + return partialMatchOnKey; + } + + @CheckForNull + public Set getProjectUuids() { + return projectUuids; + } + + @CheckForNull + public Set getProjectKeys() { + return projectKeys; + } + + @CheckForNull + public Boolean getPrivate() { + return isPrivate; + } + + @CheckForNull + public Long getAnalyzedBefore() { + return analyzedBefore; + } + + @CheckForNull + public Long getAnyBranchAnalyzedBefore() { + return anyBranchAnalyzedBefore; + } + + @CheckForNull + public Long getAnyBranchAnalyzedAfter() { + return anyBranchAnalyzedAfter; + } + + @CheckForNull + public Date getCreatedAfter() { + return createdAfter; + } + + public boolean isOnProvisionedOnly() { + return onProvisionedOnly; + } + + boolean hasEmptySetOfProjects() { + return Stream.of(projectKeys, projectUuids) + .anyMatch(list -> list != null && list.isEmpty()); + } + + public static ProjectQuery.Builder builder() { + return new ProjectQuery.Builder(); + } + + public static class Builder { + private String nameOrKeyQuery; + private Boolean partialMatchOnKey; + private Boolean isPrivate; + private Set projectUuids; + private Set projectKeys; + private Long analyzedBefore; + private Long anyBranchAnalyzedBefore; + private Long anyBranchAnalyzedAfter; + private Date createdAfter; + private boolean onProvisionedOnly = false; + + public ProjectQuery.Builder setNameOrKeyQuery(@Nullable String nameOrKeyQuery) { + this.nameOrKeyQuery = nameOrKeyQuery; + return this; + } + + /** + * Beware, can be resource intensive! Should be used with precautions. + */ + public ProjectQuery.Builder setPartialMatchOnKey(@Nullable Boolean partialMatchOnKey) { + this.partialMatchOnKey = partialMatchOnKey; + return this; + } + + public ProjectQuery.Builder setProjectUuids(@Nullable Set projectUuids) { + this.projectUuids = projectUuids; + return this; + } + + public ProjectQuery.Builder setProjectKeys(@Nullable Set projectKeys) { + this.projectKeys = projectKeys; + return this; + } + + public ProjectQuery.Builder setPrivate(@Nullable Boolean isPrivate) { + this.isPrivate = isPrivate; + return this; + } + + public ProjectQuery.Builder setAnalyzedBefore(@Nullable Long l) { + this.analyzedBefore = l; + return this; + } + + public ProjectQuery.Builder setAnyBranchAnalyzedBefore(@Nullable Long l) { + this.anyBranchAnalyzedBefore = l; + return this; + } + + /** + * Filter on date of last analysis. On projects, all branches and pull requests are taken into + * account. For example the analysis of a branch is included in the filter + * even if the main branch has never been analyzed. + */ + public ProjectQuery.Builder setAnyBranchAnalyzedAfter(@Nullable Long l) { + this.anyBranchAnalyzedAfter = l; + return this; + } + + public ProjectQuery.Builder setCreatedAfter(@Nullable Date l) { + this.createdAfter = l; + return this; + } + + public ProjectQuery.Builder setOnProvisionedOnly(boolean onProvisionedOnly) { + this.onProvisionedOnly = onProvisionedOnly; + return this; + } + + public ProjectQuery build() { + checkArgument(nameOrKeyQuery != null || partialMatchOnKey == null, "A query must be provided if a partial match on key is specified."); + return new ProjectQuery(this); + } + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/project/package-info.java b/server/sonar-db-dao/src/main/java/org/sonar/db/project/package-info.java new file mode 100644 index 00000000000..b2e9cab60f2 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/project/package-info.java @@ -0,0 +1,24 @@ +/* + * 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.db.project; + +import javax.annotation.ParametersAreNonnullByDefault; + diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java index 4e07b384823..b3a902160b1 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/property/PropertiesDao.java @@ -109,7 +109,7 @@ public class PropertiesDao implements Dao { private static PreparedStatement createStatement(String projectUuid, Collection dispatcherKeys, Connection connection) throws SQLException { String sql = "SELECT count(1) FROM properties pp " + - "left outer join projects pj on pp.resource_id = pj.id " + + "left outer join components pj on pp.resource_id = pj.id " + "where pp.user_id is not null and (pp.resource_id is null or pj.uuid=?) " + "and (" + repeat("pp.prop_key like ?", " or ", dispatcherKeys.size()) + ")"; PreparedStatement res = connection.prepareStatement(sql); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java index 7fad045f441..1cfa3e45f7f 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java @@ -283,6 +283,13 @@ class PurgeCommands { profiler.stop(); } + void deleteProject(String projectUuid) { + profiler.start("deleteProject (projects)"); + purgeMapper.deleteProjectsByProjectUuid(projectUuid); + session.commit(); + profiler.stop(); + } + void deleteComponents(List componentUuids) { if (componentUuids.isEmpty()) { return; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java index 7d335530f5b..107a444bfd9 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -211,8 +211,7 @@ public class PurgeDao implements Dao { PurgeMapper purgeMapper = mapper(session); PurgeCommands purgeCommands = new PurgeCommands(session, profiler, system2); - session.getMapper(BranchMapper.class).selectByProjectUuid(uuid) - .stream() + session.getMapper(BranchMapper.class).selectByProjectUuid(uuid).stream() .filter(branch -> !uuid.equals(branch.getUuid())) .forEach(branch -> deleteRootComponent(branch.getUuid(), purgeMapper, purgeCommands)); @@ -242,6 +241,7 @@ public class PurgeDao implements Dao { commands.deleteNewCodePeriods(rootUuid); commands.deleteBranch(rootUuid); commands.deleteComponents(rootUuid); + commands.deleteProject(rootUuid); } /** diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java index bc712a70be2..049cb8792b6 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java @@ -74,6 +74,8 @@ public interface PurgeMapper { void deleteComponentsByProjectUuid(@Param("rootUuid") String rootUuid); + void deleteProjectsByProjectUuid(@Param("projectUuid") String projectUuid); + void deleteComponentsByUuids(@Param("componentUuids") List componentUuids); void deleteGroupRolesByComponentId(@Param("rootId") long rootId); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java index d16e00382fc..83ec55bb9fa 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationDao.java @@ -31,11 +31,11 @@ public class ProjectQgateAssociationDao implements Dao { } /** - * @return quality gate uuid if a specific Quality Gate has been defined for the given component uuid.
+ * @return quality gate uuid if a specific Quality Gate has been defined for the given project uuid.
* Returns {@link Optional#empty()} otherwise (ex: default quality gate applies) */ - public Optional selectQGateUuidByComponentUuid(DbSession dbSession, String componentUuid) { - String uuid = mapper(dbSession).selectQGateUuidByComponentUuid(componentUuid); + public Optional selectQGateUuidByProjectUuid(DbSession dbSession, String projectUuid) { + String uuid = mapper(dbSession).selectQGateUuidByProjectUuid(projectUuid); return Optional.ofNullable(uuid); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java index 36db6cce990..a2c68932497 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.java @@ -28,7 +28,7 @@ public interface ProjectQgateAssociationMapper { List selectProjects(@Param("query") ProjectQgateAssociationQuery query); @CheckForNull - String selectQGateUuidByComponentUuid(String componentUuid); + String selectQGateUuidByProjectUuid(String projectUuid); void deleteByProjectUuid(String projectUuid); diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java index 763b5ac08df..02deb13e0ac 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualitygate/QualityGateDao.java @@ -107,7 +107,7 @@ public class QualityGateDao implements Dao { return session.getMapper(QualityGateMapper.class); } - public QualityGateDto selectByProjectUuid(DbSession dbSession, String uuid) { - return mapper(dbSession).selectByProjectUuid(uuid); + public QualityGateDto selectByProjectUuid(DbSession dbSession, String projectUuid) { + return mapper(dbSession).selectByProjectUuid(projectUuid); } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileDao.java index 273c089addc..90f8d985a14 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/qualityprofile/QualityProfileDao.java @@ -35,8 +35,8 @@ import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; import org.sonar.db.KeyLongValue; import org.sonar.db.RowNotFoundException; -import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.project.ProjectDto; import static com.google.common.base.Preconditions.checkArgument; import static java.util.Collections.emptyList; @@ -156,12 +156,12 @@ public class QualityProfileDao implements Dao { } @CheckForNull - public QProfileDto selectAssociatedToProjectAndLanguage(DbSession dbSession, ComponentDto project, String language) { - return mapper(dbSession).selectAssociatedToProjectUuidAndLanguage(project.getOrganizationUuid(), project.projectUuid(), language); + public QProfileDto selectAssociatedToProjectAndLanguage(DbSession dbSession, ProjectDto project, String language) { + return mapper(dbSession).selectAssociatedToProjectUuidAndLanguage(project.getOrganizationUuid(), project.getUuid(), language); } - public List selectAssociatedToProjectUuidAndLanguages(DbSession dbSession, ComponentDto project, Collection languages) { - return executeLargeInputs(languages, partition -> mapper(dbSession).selectAssociatedToProjectUuidAndLanguages(project.getOrganizationUuid(), project.uuid(), partition)); + public List selectAssociatedToProjectUuidAndLanguages(DbSession dbSession, ProjectDto project, Collection languages) { + return executeLargeInputs(languages, partition -> mapper(dbSession).selectAssociatedToProjectUuidAndLanguages(project.getOrganizationUuid(), project.getUuid(), partition)); } public List selectByLanguage(DbSession dbSession, OrganizationDto organization, String language) { @@ -205,16 +205,16 @@ public class QualityProfileDao implements Dao { return KeyLongValue.toMap(executeLargeInputs(profileUuids, partition -> mapper(dbSession).countProjectsByOrganizationAndProfiles(organization.getUuid(), partition))); } - public void insertProjectProfileAssociation(DbSession dbSession, ComponentDto project, QProfileDto profile) { - mapper(dbSession).insertProjectProfileAssociation(project.uuid(), profile.getKee()); + public void insertProjectProfileAssociation(DbSession dbSession, ProjectDto project, QProfileDto profile) { + mapper(dbSession).insertProjectProfileAssociation(project.getUuid(), profile.getKee()); } - public void deleteProjectProfileAssociation(DbSession dbSession, ComponentDto project, QProfileDto profile) { - mapper(dbSession).deleteProjectProfileAssociation(project.uuid(), profile.getKee()); + public void deleteProjectProfileAssociation(DbSession dbSession, ProjectDto project, QProfileDto profile) { + mapper(dbSession).deleteProjectProfileAssociation(project.getUuid(), profile.getKee()); } - public void updateProjectProfileAssociation(DbSession dbSession, ComponentDto project, String newProfileUuid, String oldProfileUuid) { - mapper(dbSession).updateProjectProfileAssociation(project.uuid(), newProfileUuid, oldProfileUuid); + public void updateProjectProfileAssociation(DbSession dbSession, ProjectDto project, String newProfileUuid, String oldProfileUuid) { + mapper(dbSession).updateProjectProfileAssociation(project.getUuid(), newProfileUuid, oldProfileUuid); } public void deleteProjectAssociationsByProfileUuids(DbSession dbSession, Collection profileUuids) { diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java index 5a282bf4b90..f8b1b12be31 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserDao.java @@ -36,6 +36,7 @@ import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.project.ProjectDto; import static java.util.Locale.ENGLISH; import static org.sonar.db.DatabaseUtils.executeLargeInputs; @@ -143,6 +144,10 @@ public class UserDao implements Dao { mapper(dbSession).clearHomepages("ORGANIZATION", organization.getUuid(), system2.now()); } + public void cleanHomepage(DbSession dbSession, ProjectDto project) { + mapper(dbSession).clearHomepages("PROJECT", project.getUuid(), system2.now()); + } + public void cleanHomepage(DbSession dbSession, ComponentDto project) { mapper(dbSession).clearHomepages("PROJECT", project.uuid(), system2.now()); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDao.java index 98d3d5ef671..bbed39b4fa0 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/webhook/WebhookDao.java @@ -26,6 +26,7 @@ import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.project.ProjectDto; import static com.google.common.base.Preconditions.checkState; @@ -49,8 +50,8 @@ public class WebhookDao implements Dao { return mapper(dbSession).selectForOrganizationUuidOrderedByName(organizationUuid); } - public List selectByProject(DbSession dbSession, ComponentDto componentDto) { - return mapper(dbSession).selectForProjectUuidOrderedByName(componentDto.uuid()); + public List selectByProject(DbSession dbSession, ProjectDto projectDto) { + return mapper(dbSession).selectForProjectUuidOrderedByName(projectDto.getUuid()); } public void insert(DbSession dbSession, WebhookDto dto) { @@ -73,8 +74,8 @@ public class WebhookDao implements Dao { mapper(dbSession).deleteForOrganizationUuid(organization.getUuid()); } - public void deleteByProject(DbSession dbSession, ComponentDto componentDto) { - mapper(dbSession).deleteForProjectUuid(componentDto.uuid()); + public void deleteByProject(DbSession dbSession, ProjectDto projectDto) { + mapper(dbSession).deleteForProjectUuid(projectDto.getUuid()); } private static WebhookMapper mapper(DbSession dbSession) { diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/ProjectAlmBindingMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/ProjectAlmBindingMapper.xml index 845af9e7d2e..96152fe03a1 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/ProjectAlmBindingMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/alm/ProjectAlmBindingMapper.xml @@ -95,7 +95,7 @@ p.kee as projectKey from project_alm_bindings b - inner join projects p + inner join components p on b.project_uuid = p.project_uuid where alm_id = #{almId, jdbcType=VARCHAR} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml index d65e0a48a69..50a30adbbc9 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/BranchMapper.xml @@ -76,6 +76,16 @@ pb.key_type = #{keyType, jdbcType=VARCHAR} + + SELECT count(1) - FROM projects + FROM components WHERE kee = #{key,jdbcType=VARCHAR} - - update projects + + update components set kee = #{key,jdbcType=VARCHAR}, deprecated_kee = #{deprecatedKey,jdbcType=VARCHAR} where id = #{id,jdbcType=BIGINT} + + update projects + set kee = #{newProjectKey,jdbcType=VARCHAR} + where kee = #{oldProjectKey,jdbcType=VARCHAR} + + diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml index 6134fb1eda2..3acf8b919bf 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -30,7 +30,7 @@ @@ -38,7 +38,7 @@ select - from projects p + from components p inner join project_branches pb on pb.uuid = p.project_uuid where (p.kee=#{dbKey,jdbcType=VARCHAR} OR p.kee=#{key,jdbcType=VARCHAR}) @@ -60,14 +60,14 @@ @@ -76,7 +76,7 @@ select from - projects p + components p inner join project_alm_bindings pab on pab.project_uuid = p.uuid where @@ -86,8 +86,8 @@ @@ -95,7 +95,7 @@ select - from projects p + from components p where p.enabled=${_true} and p.kee in @@ -120,7 +120,7 @@ select - from projects p + from components p where p.enabled=${_true} and p.id in @@ -147,7 +147,7 @@ select p.uuid - from projects p + from components p where p.uuid in @@ -168,8 +168,8 @@ SELECT - FROM projects p + FROM components p - INNER JOIN projects module ON + INNER JOIN components module ON module.project_uuid = p.project_uuid and module.organization_uuid = p.organization_uuid and module.uuid = #{moduleUuid} @@ -218,8 +218,8 @@ p.module_uuid as moduleUuid, fs.src_hash as srcHash, fs.revision - FROM projects root - INNER JOIN projects p on + FROM components root + INNER JOIN components p on p.project_uuid=root.uuid and p.organization_uuid=root.organization_uuid and p.enabled=${_true} @@ -237,7 +237,7 @@ p.module_uuid as moduleUuid, fs.src_hash as srcHash, fs.revision - FROM projects p + FROM components p INNER JOIN file_sources fs ON fs.file_uuid=p.uuid @@ -246,7 +246,7 @@ select - from projects p + from components p where p.enabled=${_true} and p.scope='PRJ' @@ -269,7 +269,7 @@ select count(1) - from projects p + from components p where p.enabled=${_true} and p.project_uuid = #{projectUuid,jdbcType=VARCHAR} @@ -289,7 +289,7 @@ - from projects p + from components p inner join snapshots sa on sa.component_uuid=p.uuid and sa.status='P' and sa.islast=${_true} and sa.created_at < #{query.analyzedBefore,jdbcType=BIGINT} @@ -424,7 +424,7 @@ - inner join projects base on base.project_uuid = p.project_uuid and base.uuid = #{baseUuid} + inner join components base on base.project_uuid = p.project_uuid and base.uuid = #{baseUuid} and p.uuid_path = #{baseUuidPath,jdbcType=VARCHAR} @@ -467,7 +467,7 @@ select distinct p.kee - from projects p - inner join projects leaf on + from components p + inner join components leaf on leaf.qualifier = 'TRK' and leaf.scope = 'FIL' and leaf.enabled = ${_true} @@ -493,7 +493,7 @@ SELECT - FROM projects p - INNER JOIN projects root ON root.uuid=p.project_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR} + FROM components p + INNER JOIN components root ON root.uuid=p.project_uuid AND root.kee=#{projectKey,jdbcType=VARCHAR} p.enabled = ${_true} @@ -521,24 +521,24 @@ SELECT p.uuid as uuid, p.module_uuid as moduleUuid, p.path as path, p.scope as scope FROM - projects p + components p INNER JOIN - projects root ON root.uuid=p.project_uuid AND p.enabled = ${_true} AND root.kee=#{projectKey,jdbcType=VARCHAR} + components root ON root.uuid=p.project_uuid AND p.enabled = ${_true} AND root.kee=#{projectKey,jdbcType=VARCHAR} - INSERT INTO projects ( + INSERT INTO components ( organization_uuid, kee, uuid, @@ -640,14 +640,14 @@ - update projects set + update components set tags = #{tagsString,jdbcType=VARCHAR} where uuid = #{uuid,jdbcType=VARCHAR} - update projects set + update components set b_changed = #{bChanged,jdbcType=BOOLEAN}, deprecated_kee = #{bKey,jdbcType=VARCHAR}, @@ -667,7 +667,7 @@ - update projects set + update components set b_changed = ${_true}, deprecated_kee = kee, @@ -687,7 +687,7 @@ - update projects set + update components set kee = deprecated_kee, copy_component_uuid = b_copy_component_uuid, @@ -733,7 +733,7 @@ - update projects + update components set b_changed = ${_false}, deprecated_kee = kee @@ -743,7 +743,7 @@ - update projects set + update components set private = #{isPrivate,jdbcType=BOOLEAN} where project_uuid = #{projectUuid,jdbcType=VARCHAR} @@ -751,11 +751,11 @@ - DELETE FROM projects WHERE id=#{id,jdbcType=BIGINT} + DELETE FROM components WHERE id=#{id,jdbcType=BIGINT} select from snapshots s - inner join projects p on s.component_uuid = p.project_uuid + inner join components p on s.component_uuid = p.project_uuid where s.islast=${_true} and p.uuid = #{componentUuid,jdbcType=VARCHAR} @@ -67,7 +67,7 @@ FROM snapshots s - INNER JOIN projects p ON p.uuid=s.component_uuid AND p.enabled=${_true} AND s.component_uuid=#{query.componentUuid,jdbcType=VARCHAR} + INNER JOIN components p ON p.uuid=s.component_uuid AND p.enabled=${_true} AND s.component_uuid=#{query.componentUuid,jdbcType=VARCHAR} @@ -104,7 +104,7 @@ select from snapshots s - inner join projects p on p.uuid=s.component_uuid and p.enabled=${_true} + inner join components p on p.uuid=s.component_uuid and p.enabled=${_true} inner join project_branches pb on pb.uuid=p.uuid where diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/duplication/DuplicationMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/duplication/DuplicationMapper.xml index d24950c4c99..64f3fc648b5 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/duplication/DuplicationMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/duplication/DuplicationMapper.xml @@ -15,7 +15,7 @@ file_component.kee as componentKey FROM duplications_index duplication_block INNER JOIN snapshots snapshot ON duplication_block.analysis_uuid=snapshot.uuid AND snapshot.islast=${_true} - INNER JOIN projects file_component ON file_component.uuid=duplication_block.component_uuid AND file_component.language=#{language} + INNER JOIN components file_component ON file_component.uuid=duplication_block.component_uuid AND file_component.language=#{language} AND file_component.enabled=${_true} AND duplication_block.hash in diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml index 37ea21fbe49..368414c60a7 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/issue/IssueMapper.xml @@ -181,8 +181,8 @@ from issues i inner join rules r on r.id=i.rule_id - inner join projects p on p.uuid=i.component_uuid - inner join projects root on root.uuid=i.project_uuid + inner join components p on p.uuid=i.component_uuid + inner join components root on root.uuid=i.project_uuid where i.kee=#{kee,jdbcType=VARCHAR} @@ -191,8 +191,8 @@ from issues i inner join rules r on r.id=i.rule_id - inner join projects p on p.uuid=i.component_uuid - inner join projects root on root.uuid=i.project_uuid + inner join components p on p.uuid=i.component_uuid + inner join components root on root.uuid=i.project_uuid where i.component_uuid = #{componentUuid,jdbcType=VARCHAR} and i.status <> 'CLOSED' @@ -203,8 +203,8 @@ from issues i inner join rules r on r.id=i.rule_id - inner join projects p on p.uuid=i.component_uuid - inner join projects root on root.uuid=i.project_uuid + inner join components p on p.uuid=i.component_uuid + inner join components root on root.uuid=i.project_uuid where (r.is_external is NULL or r.is_external = ${_false}) and i.component_uuid = #{componentUuid,jdbcType=VARCHAR} and @@ -219,9 +219,9 @@ from issues i inner join rules r on r.id = i.rule_id - inner join projects p on + inner join components p on p.uuid = i.component_uuid - inner join projects root on + inner join components root on root.uuid = i.project_uuid inner join issue_changes ic on ic.issue_key = i.kee @@ -241,7 +241,7 @@ select distinct(i.component_uuid) from issues i - inner join projects p on + inner join components p on p.uuid = i.component_uuid and p.enabled = ${_true} where @@ -261,8 +261,8 @@ from issues i inner join rules r on r.id=i.rule_id - inner join projects p on p.uuid=i.component_uuid - inner join projects root on root.uuid=i.project_uuid + inner join components p on p.uuid=i.component_uuid + inner join components root on root.uuid=i.project_uuid where i.kee in #{key,jdbcType=VARCHAR} @@ -274,8 +274,8 @@ from issues i inner join rules r on r.id=i.rule_id - inner join projects p on p.uuid=i.component_uuid - inner join projects root on root.uuid=i.project_uuid + inner join components p on p.uuid=i.component_uuid + inner join components root on root.uuid=i.project_uuid where i.kee in @@ -311,8 +311,8 @@ from issues i inner join rules r on r.id = i.rule_id - inner join projects p on p.uuid = i.component_uuid - inner join projects root on root.uuid = i.project_uuid + inner join components p on p.uuid = i.component_uuid + inner join components root on root.uuid = i.project_uuid where (r.is_external is NULL or r.is_external = ${_false}) and i.project_uuid = #{projectUuid, jdbcType=VARCHAR} and @@ -324,7 +324,7 @@ select from live_measures lm - inner join projects p on p.uuid = lm.component_uuid - + inner join components p on p.uuid = lm.component_uuid + @@ -196,7 +196,7 @@ -- Add measures of base component union all select from live_measures lm - inner join projects p on p.uuid = lm.component_uuid and lm.component_uuid = #{baseUuid, jdbcType=VARCHAR} + inner join components p on p.uuid = lm.component_uuid and lm.component_uuid = #{baseUuid, jdbcType=VARCHAR} lm.metric_id in diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml index a5d4d313c7b..64c92258fdc 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml @@ -64,7 +64,7 @@ select p.uuid - from projects p + from components p inner join group_roles gr on p.id = gr.resource_id where gr.role = #{permission, jdbcType=VARCHAR} @@ -267,7 +267,7 @@ union select p.uuid - from projects p + from components p inner join user_roles ur on p.id = ur.resource_id where ur.role=#{permission, jdbcType=VARCHAR} @@ -278,7 +278,7 @@ union select p.uuid - from projects p + from components p where p.uuid in #{projectUuid, jdbcType=VARCHAR} and p.private = ${_false} @@ -287,7 +287,7 @@ select ur.role from user_roles ur - inner join projects p on p.id = ur.resource_id + inner join components p on p.id = ur.resource_id where p.uuid = #{projectUuid, jdbcType=VARCHAR} and p.organization_uuid = ur.organization_uuid and @@ -371,7 +371,7 @@ select gr.role from group_roles gr inner join groups_users gu on gr.group_id = gu.group_id - inner join projects p on p.id = gr.resource_id + inner join components p on p.id = gr.resource_id where p.uuid = #{projectUuid, jdbcType=VARCHAR} and p.organization_uuid = gr.organization_uuid and @@ -391,7 +391,7 @@ gr.role from group_roles gr - inner join projects p on + inner join components p on p.id = gr.resource_id where p.uuid = #{projectUuid, jdbcType=VARCHAR} @@ -440,14 +440,14 @@ exists ( select 1 from user_roles ur - inner join projects p on p.id = ur.resource_id and p.organization_uuid = ur.organization_uuid + inner join components p on p.id = ur.resource_id and p.organization_uuid = ur.organization_uuid where p.kee = #{projectKey, jdbcType=VARCHAR} and ur.role = #{permission, jdbcType=VARCHAR} and ur.user_id = u.id ) or exists ( select 1 - from projects p + from components p inner join group_roles gr on gr.resource_id = p.id and gr.organization_uuid = p.organization_uuid inner join groups_users gu on gu.group_id = gr.group_id where @@ -458,7 +458,7 @@ or exists ( select 1 - from projects p + from components p where p.kee = #{projectKey, jdbcType=VARCHAR} and p.private = ${_false} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml index 11cc02aca6c..dda0afa919e 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml @@ -85,7 +85,7 @@ ) sub - left join projects p on sub.componentId = p.id + left join components p on sub.componentId = p.id and lower(sub.name) like #{query.searchQueryToSqlLowercase,jdbcType=VARCHAR} ESCAPE '/' diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml index 71d6b929116..2df73ecf881 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml @@ -40,7 +40,7 @@ and ur.resource_id = #{query.componentId,jdbcType=BIGINT} - left join projects p on ur.resource_id = p.id + left join components p on ur.resource_id = p.id inner join organization_members om on u.id=om.user_id and om.organization_uuid=#{query.organizationUuid,jdbcType=VARCHAR} @@ -60,7 +60,7 @@ from users u left join user_roles ur on ur.user_id = u.id - left join projects p on ur.resource_id = p.id + left join components p on ur.resource_id = p.id inner join organization_members om on u.id=om.user_id and om.organization_uuid=#{query.organizationUuid,jdbcType=VARCHAR} @@ -109,7 +109,7 @@ select ur.resource_id as componentId, ur.role as permission, count(u.login) as count from users u inner join user_roles ur on ur.user_id = u.id - inner join projects p on p.id = ur.resource_id + inner join components p on p.id = ur.resource_id where u.active = ${_true} and p.id in #{projectId} group by ur.resource_id, ur.role diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml new file mode 100644 index 00000000000..761d1f01e49 --- /dev/null +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/project/ProjectMapper.xml @@ -0,0 +1,144 @@ + + + + + + p.uuid as uuid, + p.organization_uuid as organizationUuid, + p.kee as kee, + p.qualifier as qualifier, + p.name as name, + p.description as description, + p.tags as tagsString, + p.private as isPrivate, + p.created_at as createdAt, + p.updated_at as updatedAt + + + + + + + + + + + + + + + + + + + + + + INSERT INTO projects ( + organization_uuid, + kee, + qualifier, + uuid, + name, + description, + private, + tags, + created_at, + updated_at + ) + VALUES ( + #{organizationUuid,jdbcType=VARCHAR}, + #{kee,jdbcType=VARCHAR}, + #{qualifier,jdbcType=VARCHAR}, + #{uuid,jdbcType=VARCHAR}, + #{name,jdbcType=VARCHAR}, + #{description,jdbcType=VARCHAR}, + #{isPrivate,jdbcType=BOOLEAN}, + #{tagsString, jdbcType=VARCHAR}, + #{createdAt,jdbcType=BIGINT}, + #{updatedAt,jdbcType=BIGINT} + ) + + + + update projects set + tags = #{tagsString,jdbcType=VARCHAR}, + updated_at = #{updatedAt,jdbcType=BIGINT} + where + uuid = #{uuid,jdbcType=VARCHAR} + + + + update projects set + name = #{name,jdbcType=VARCHAR}, + description = #{description,jdbcType=VARCHAR}, + updated_at = #{updatedAt,jdbcType=BIGINT} + where + uuid = #{uuid,jdbcType=VARCHAR} + + + diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/InternalComponentPropertiesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/InternalComponentPropertiesMapper.xml index 0a079a62524..bc11d47d539 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/InternalComponentPropertiesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/InternalComponentPropertiesMapper.xml @@ -25,7 +25,7 @@ FROM internal_component_props icp JOIN - projects p + components p ON icp.component_uuid = p.uuid diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml index 1af78ca7308..ac862b11999 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/property/PropertiesMapper.xml @@ -23,7 +23,7 @@ ${_false} as "global" FROM users u - INNER JOIN projects c on c.kee = #{projectKey,jdbcType=VARCHAR} + INNER JOIN components c on c.kee = #{projectKey,jdbcType=VARCHAR} INNER JOIN properties p ON p.user_id = u.id WHERE p.prop_key = #{notifKey,jdbcType=VARCHAR} @@ -59,7 +59,7 @@ u.email as "email" FROM users u - INNER JOIN projects c on + INNER JOIN components c on c.kee = #{projectKey,jdbcType=VARCHAR} INNER JOIN properties p ON p.user_id = u.id @@ -99,7 +99,7 @@ from properties p, - projects r + components r where p.resource_id=r.id and p.user_id is null @@ -177,7 +177,7 @@ from properties p - inner join projects prj on prj.id=p.resource_id and prj.qualifier = #{qualifier, jdbcType=VARCHAR} + inner join components prj on prj.id=p.resource_id and prj.qualifier = #{qualifier, jdbcType=VARCHAR} where p.prop_key = #{key, jdbcType=VARCHAR} and p.user_id = #{userId, jdbcType=INTEGER} @@ -204,7 +204,7 @@ select py.id from properties py - inner join projects ps on py.resource_id = ps.id + inner join components ps on py.resource_id = ps.id where py.text_value like #{login,jdbcType=VARCHAR} and py.prop_key in diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml index add001d2975..2d1dffdcf62 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml @@ -66,7 +66,7 @@ select p.id, p.uuid from - projects p + components p where ( p.project_uuid=#{rootUuid,jdbcType=VARCHAR} @@ -82,7 +82,7 @@ select file_uuid from file_sources fs - inner join projects p on + inner join components p on p.uuid = fs.file_uuid and p.enabled = ${_false} and p.project_uuid=#{projectUuid,jdbcType=VARCHAR} @@ -92,7 +92,7 @@ select i.component_uuid from issues i - inner join projects p on + inner join components p on p.uuid = i.component_uuid and p.enabled = ${_false} and p.project_uuid=#{projectUuid,jdbcType=VARCHAR} @@ -104,7 +104,7 @@ select lm.component_uuid from live_measures lm - inner join projects p on + inner join components p on p.uuid = lm.component_uuid and p.enabled = ${_false} and p.project_uuid=#{projectUuid,jdbcType=VARCHAR} @@ -245,13 +245,19 @@ - delete from projects + delete from components where project_uuid = #{rootUuid,jdbcType=VARCHAR} - + delete from projects + where + uuid = #{projectUuid,jdbcType=VARCHAR} + + + + delete from components where uuid in @@ -340,7 +346,7 @@ SELECT p.id, p.uuid FROM - projects p + components p WHERE p.enabled = ${_false} AND p.project_uuid=#{projectUuid,jdbcType=VARCHAR} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml index e0ce3f079ff..d99aea3a41d 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualitygate/ProjectQgateAssociationMapper.xml @@ -3,9 +3,9 @@ - SELECT proj.id as id, proj.kee as "key", proj.name as name, qg.id as gateId - FROM projects proj + FROM components proj LEFT JOIN project_qgates prqg ON prqg.project_uuid=proj.uuid AND prqg.quality_gate_uuid = #{query.gateUuid, jdbcType=VARCHAR} LEFT JOIN quality_gates qg ON qg.uuid = prqg.quality_gate_uuid where @@ -28,11 +28,11 @@ order by proj.name - SELECT quality_gate_uuid FROM project_qgates - AND project_uuid=#{componentUuid} + AND project_uuid=#{projectUuid} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QualityProfileMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QualityProfileMapper.xml index 5a74720b17a..a8c61196813 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QualityProfileMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/qualityprofile/QualityProfileMapper.xml @@ -261,7 +261,7 @@ SELECT pp.id as id, pj.id as projectId, pj.uuid as projectUuid, pj.kee as projectKey, pj.name as projectName, pp.profile_key as profileKey - FROM projects pj + FROM components pj LEFT JOIN project_qprofiles pp ON pp.project_uuid = pj.uuid AND pp.profile_key = #{profileUuid, jdbcType=VARCHAR} WHERE pj.scope='PRJ' AND pj.qualifier='TRK' AND pj.main_branch_project_uuid is null @@ -365,7 +365,7 @@