From 1233df6661da5509b526411f0adca64673799031 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Thu, 15 Jul 2021 13:35:54 -0500 Subject: [PATCH] SONAR-11411 Detection of inactive projects should take into account branches --- .../sonar/db/component/ComponentQuery.java | 17 +++- .../component/ProjectLastAnalysisDateDto.java | 38 +++++++++ .../org/sonar/db/component/SnapshotDao.java | 17 ++++ .../sonar/db/component/SnapshotMapper.java | 4 + .../sonar/db/component/ComponentMapper.xml | 28 ++++++- .../org/sonar/db/component/SnapshotMapper.xml | 23 +++++- .../sonar/db/component/ComponentDaoTest.java | 49 +++++++++++- .../sonar/db/component/SnapshotDaoTest.java | 78 ++++++++++++++++--- .../server/project/ws/BulkDeleteAction.java | 2 +- .../sonar/server/project/ws/SearchAction.java | 21 +++-- .../project/ws/BulkDeleteActionTest.java | 4 +- .../server/project/ws/SearchActionTest.java | 29 +++++-- 12 files changed, 276 insertions(+), 34 deletions(-) create mode 100644 server/sonar-db-dao/src/main/java/org/sonar/db/component/ProjectLastAnalysisDateDto.java diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java index 437de943e97..8324a273cb2 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java @@ -40,6 +40,7 @@ public class ComponentQuery { private final Long analyzedBefore; private final Long anyBranchAnalyzedBefore; private final Long anyBranchAnalyzedAfter; + private final Long allBranchesAnalyzedBefore; private final Date createdAfter; private final boolean onProvisionedOnly; @@ -53,6 +54,7 @@ public class ComponentQuery { this.analyzedBefore = builder.analyzedBefore; this.anyBranchAnalyzedBefore = builder.anyBranchAnalyzedBefore; this.anyBranchAnalyzedAfter = builder.anyBranchAnalyzedAfter; + this.allBranchesAnalyzedBefore = builder.allBranchesAnalyzedBefore; this.createdAfter = builder.createdAfter; this.onProvisionedOnly = builder.onProvisionedOnly; } @@ -111,6 +113,11 @@ public class ComponentQuery { return anyBranchAnalyzedAfter; } + @CheckForNull + public Long getAllBranchesAnalyzedBefore() { + return allBranchesAnalyzedBefore; + } + @CheckForNull public Date getCreatedAfter() { return createdAfter; @@ -139,6 +146,7 @@ public class ComponentQuery { private Long analyzedBefore; private Long anyBranchAnalyzedBefore; private Long anyBranchAnalyzedAfter; + private Long allBranchesAnalyzedBefore; private Date createdAfter; private boolean onProvisionedOnly = false; @@ -180,8 +188,8 @@ public class ComponentQuery { return this; } - public Builder setAnyBranchAnalyzedBefore(@Nullable Long l) { - this.anyBranchAnalyzedBefore = l; + public Builder setAllBranchesAnalyzedBefore(@Nullable Long l) { + this.allBranchesAnalyzedBefore = l; return this; } @@ -195,6 +203,11 @@ public class ComponentQuery { return this; } + public Builder setAnyBranchAnalyzedBefore(@Nullable Long l) { + this.anyBranchAnalyzedBefore = l; + return this; + } + public Builder setCreatedAfter(@Nullable Date l) { this.createdAfter = l; return this; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ProjectLastAnalysisDateDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ProjectLastAnalysisDateDto.java new file mode 100644 index 00000000000..ee6da259363 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ProjectLastAnalysisDateDto.java @@ -0,0 +1,38 @@ +/* + * SonarQube + * Copyright (C) 2009-2021 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.component; + +public class ProjectLastAnalysisDateDto { + private final String projectUuid; + private final Long date; + + public ProjectLastAnalysisDateDto(String projectUuid, Long date) { + this.projectUuid = projectUuid; + this.date = date; + } + + public String getProjectUuid() { + return projectUuid; + } + + public Long getDate() { + return date; + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java index 79f358ac4d5..ce45f1f347a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotDao.java @@ -59,6 +59,23 @@ public class SnapshotDao implements Dao { return Optional.ofNullable(mapper(session).selectLastSnapshotByComponentUuid(componentUuid)); } + /** + * returns the last analysis of any branch of a project + */ + public Optional selectLastAnalysisDateByProject(DbSession session, String projectUuid) { + return Optional.ofNullable(mapper(session).selectLastAnalysisDateByProject(projectUuid)); + } + + /** + * returns the last analysis of any branch for each existing project + */ + public List selectLastAnalysisDateByProjects(DbSession session, Collection projectUuids) { + if (projectUuids.isEmpty()) { + return Collections.emptyList(); + } + return mapper(session).selectLastAnalysisDateByProjects(projectUuids); + } + public Optional selectLastAnalysisByRootComponentUuid(DbSession session, String componentUuid) { return Optional.ofNullable(mapper(session).selectLastSnapshotByRootComponentUuid(componentUuid)); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java index 04044f4d16a..fdccc8f82a0 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/SnapshotMapper.java @@ -54,4 +54,8 @@ public interface SnapshotMapper { List selectFinishedByComponentUuidsAndFromDates(@Param("componentUuidFromDatePairs") List pairs); + @CheckForNull + Long selectLastAnalysisDateByProject(String projectUuid); + + List selectLastAnalysisDateByProjects(@Param("projectUuids") Collection projectUuids); } 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 87d255caefb..97198772fbc 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 @@ -311,7 +311,7 @@ and ( exists( - -- branches of projects + -- branches of projects and applications select 1 from snapshots s inner join project_branches pb on s.component_uuid = pb.uuid where pb.project_uuid = p.uuid @@ -320,7 +320,7 @@ and s.created_at >= #{query.anyBranchAnalyzedAfter,jdbcType=BIGINT} ) or exists ( - -- applications, portfolios + -- portfolios select 1 from snapshots s where s.component_uuid = p.uuid and s.status='P' @@ -332,7 +332,7 @@ and ( exists( - -- branches of projects + -- branches of projects and applications select 1 from snapshots s inner join project_branches pb on s.component_uuid = pb.uuid where pb.project_uuid = p.uuid @@ -341,7 +341,7 @@ and s.created_at < #{query.anyBranchAnalyzedBefore,jdbcType=BIGINT} ) or exists ( - -- applications, portfolios + -- portfolios select 1 from snapshots s where s.component_uuid = p.uuid and s.status='P' @@ -350,6 +350,26 @@ ) ) + + and + ( + (select max(s.created_at) from snapshots s + inner join project_branches pb on s.component_uuid = pb.uuid + where pb.project_uuid = p.uuid + and s.status='P' + and s.islast = ${_true} + ) < #{query.allBranchesAnalyzedBefore,jdbcType=BIGINT} + or + exists ( + -- portfolios + select 1 from snapshots s + where s.component_uuid = p.uuid + and p.qualifier = 'VW' + and s.status='P' + and s.islast = ${_true} + and s.created_at < #{query.allBranchesAnalyzedBefore,jdbcType=BIGINT}) + ) + and p.created_at >= #{query.createdAfter,jdbcType=TIMESTAMP} diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml index aa53f2e4b82..577547b007a 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/SnapshotMapper.xml @@ -4,7 +4,7 @@ s.uuid as uuid, - s.component_uuid as componentUuId, + s.component_uuid as componentUuid, s.created_at as createdAt, s.build_date as buildDate, s.status as status, @@ -44,6 +44,27 @@ and p.uuid = #{componentUuid,jdbcType=VARCHAR} + + + +