diff options
author | Daniel Schwarz <daniel.schwarz@sonarsource.com> | 2017-11-23 11:13:26 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-12-05 09:29:16 +0100 |
commit | d987a6a527bc10734fd9402ce728d27359ccdc41 (patch) | |
tree | d7ab4aa81326e522a512d8674f6a59ba282c45ae /server/sonar-db-dao/src/main/java/org/sonar/db | |
parent | 05677f8e3e0a0a281dd6adbbcbad9a4be7cfaea6 (diff) | |
download | sonarqube-d987a6a527bc10734fd9402ce728d27359ccdc41.tar.gz sonarqube-d987a6a527bc10734fd9402ce728d27359ccdc41.zip |
SONAR-10116 Better scalability of loading of project measures
Diffstat (limited to 'server/sonar-db-dao/src/main/java/org/sonar/db')
19 files changed, 375 insertions, 171 deletions
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 06a3216c6c7..e9419b755fb 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 @@ -39,6 +39,7 @@ import org.sonar.db.es.EsQueueDao; import org.sonar.db.event.EventDao; import org.sonar.db.issue.IssueChangeDao; import org.sonar.db.issue.IssueDao; +import org.sonar.db.measure.LiveMeasureDao; import org.sonar.db.measure.MeasureDao; import org.sonar.db.measure.custom.CustomMeasureDao; import org.sonar.db.metric.MetricDao; @@ -92,6 +93,7 @@ public class DaoModule extends Module { ComponentDao.class, ComponentKeyUpdaterDao.class, ComponentLinkDao.class, + LiveMeasureDao.class, CustomMeasureDao.class, DefaultQProfileDao.class, DuplicationDao.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 1cc3778af49..ce3e71e8087 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 @@ -37,6 +37,7 @@ import org.sonar.db.es.EsQueueDao; import org.sonar.db.event.EventDao; import org.sonar.db.issue.IssueChangeDao; import org.sonar.db.issue.IssueDao; +import org.sonar.db.measure.LiveMeasureDao; import org.sonar.db.measure.MeasureDao; import org.sonar.db.measure.custom.CustomMeasureDao; import org.sonar.db.metric.MetricDao; @@ -130,6 +131,7 @@ public class DbClient { private final AnalysisPropertiesDao analysisPropertiesDao; private final QProfileEditUsersDao qProfileEditUsersDao; private final QProfileEditGroupsDao qProfileEditGroupsDao; + private final LiveMeasureDao liveMeasureDao; public DbClient(Database database, MyBatis myBatis, DBSessions dbSessions, Dao... daos) { this.database = database; @@ -191,6 +193,7 @@ public class DbClient { analysisPropertiesDao = getDao(map, AnalysisPropertiesDao.class); qProfileEditUsersDao = getDao(map, QProfileEditUsersDao.class); qProfileEditGroupsDao = getDao(map, QProfileEditGroupsDao.class); + liveMeasureDao = getDao(map, LiveMeasureDao.class); } public DbSession openSession(boolean batch) { @@ -405,6 +408,10 @@ public class DbClient { return qProfileEditGroupsDao; } + public LiveMeasureDao liveMeasureDao() { + return liveMeasureDao; + } + protected <K extends Dao> K getDao(Map<Class, Dao> map, Class<K> clazz) { return (K) map.get(clazz); } 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 03f2eb1a556..0310390b272 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 @@ -62,6 +62,7 @@ import org.sonar.db.issue.IssueChangeMapper; import org.sonar.db.issue.IssueDto; import org.sonar.db.issue.IssueMapper; import org.sonar.db.issue.ShortBranchIssueDto; +import org.sonar.db.measure.LiveMeasureMapper; import org.sonar.db.measure.MeasureDto; import org.sonar.db.measure.MeasureMapper; import org.sonar.db.measure.custom.CustomMeasureDto; @@ -207,6 +208,7 @@ public class MyBatis implements Startable { ComponentKeyUpdaterMapper.class, ComponentLinkMapper.class, ComponentMapper.class, + LiveMeasureMapper.class, CustomMeasureMapper.class, DefaultQProfileMapper.class, DuplicationMapper.class, diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java index 9e69d55f2d9..65e14a2d8a8 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDto.java @@ -138,7 +138,6 @@ public class ComponentDto { private String moduleUuid; private String moduleUuidPath; private String copyComponentUuid; - private String developerUuid; private String scope; private String qualifier; private String path; @@ -401,16 +400,6 @@ public class ComponentDto { return this; } - @CheckForNull - public String getDeveloperUuid() { - return developerUuid; - } - - public ComponentDto setDeveloperUuid(@Nullable String developerUuid) { - this.developerUuid = developerUuid; - return this; - } - public Date getCreatedAt() { return createdAt; } @@ -488,7 +477,6 @@ public class ComponentDto { .append("rootUuid", rootUuid) .append("mainBranchProjectUuid", mainBranchProjectUuid) .append("copyComponentUuid", copyComponentUuid) - .append("developerUuid", developerUuid) .append("path", path) .append("deprecatedKey", deprecatedKey) .append("name", name) @@ -513,7 +501,6 @@ public class ComponentDto { copy.moduleUuid = moduleUuid; copy.moduleUuidPath = moduleUuidPath; copy.copyComponentUuid = copyComponentUuid; - copy.developerUuid = developerUuid; copy.scope = scope; copy.qualifier = qualifier; copy.path = path; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ResourceDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ResourceDto.java index b8cc1cf53f6..46b06fe7a48 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ResourceDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ResourceDto.java @@ -45,7 +45,6 @@ public class ResourceDto { private String description; private String language; private String copyComponentUuid; - private String developerUuid; private Date createdAt; public Long getId() { @@ -202,16 +201,6 @@ public class ResourceDto { return this; } - @CheckForNull - public String getDeveloperUuid() { - return developerUuid; - } - - public ResourceDto setDeveloperUuid(@Nullable String developerUuid) { - this.developerUuid = developerUuid; - return this; - } - public Date getCreatedAt() { return createdAt; } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java new file mode 100644 index 00000000000..353e1297327 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDao.java @@ -0,0 +1,100 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.measure; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; +import org.apache.ibatis.session.ResultHandler; +import org.sonar.api.utils.System2; +import org.sonar.core.util.Uuids; +import org.sonar.db.Dao; +import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentDto; + +import static java.util.Collections.singletonList; +import static org.sonar.db.DatabaseUtils.executeLargeInputs; + +public class LiveMeasureDao implements Dao { + + private final System2 system2; + + public LiveMeasureDao(System2 system2) { + this.system2 = system2; + } + + public List<LiveMeasureDto> selectByComponentUuids(DbSession dbSession, Collection<String> largeComponentUuids, Collection<Integer> metricIds) { + if (largeComponentUuids.isEmpty() || metricIds.isEmpty()) { + return Collections.emptyList(); + } + + return executeLargeInputs( + largeComponentUuids, + componentUuids -> mapper(dbSession).selectByComponentUuidsAndMetricIds(componentUuids, metricIds)); + } + + public List<LiveMeasureDto> selectByComponentUuidsAndMetricKeys(DbSession dbSession, Collection<String> largeComponentUuids, Collection<String> metricKeys) { + if (largeComponentUuids.isEmpty() || metricKeys.isEmpty()) { + return Collections.emptyList(); + } + + return executeLargeInputs( + largeComponentUuids, + componentUuids -> mapper(dbSession).selectByComponentUuidsAndMetricKeys(componentUuids, metricKeys)); + } + + public Optional<LiveMeasureDto> selectMeasure(DbSession dbSession, String componentUuid, String metricKey) { + List<LiveMeasureDto> measures = selectByComponentUuidsAndMetricKeys(dbSession, singletonList(componentUuid), singletonList(metricKey)); + // couple of columns [component_uuid, metric_id] is unique. List can't have more than 1 item. + if (measures.size() == 1) { + return Optional.of(measures.get(0)); + } + return Optional.empty(); + } + + public void selectTreeByQuery(DbSession dbSession, ComponentDto baseComponent, MeasureTreeQuery query, ResultHandler<LiveMeasureDto> resultHandler) { + if (query.returnsEmpty()) { + return; + } + mapper(dbSession).selectTreeByQuery(query, baseComponent.uuid(), query.getUuidPath(baseComponent), resultHandler); + } + + public void insert(DbSession dbSession, LiveMeasureDto dto) { + mapper(dbSession).insert(dto, Uuids.create(), null, system2.now()); + } + + public void insertOrUpdate(DbSession dbSession, LiveMeasureDto dto, @Nullable String marker) { + LiveMeasureMapper mapper = mapper(dbSession); + long now = system2.now(); + if (mapper.update(dto, marker, now) == 0) { + mapper.insert(dto, Uuids.create(), marker, now); + } + } + + public void deleteByProjectUuidExcludingMarker(DbSession dbSession, String projectUuid, String marker) { + mapper(dbSession).deleteByProjectUuidExcludingMarker(projectUuid, marker); + } + + private static LiveMeasureMapper mapper(DbSession dbSession) { + return dbSession.getMapper(LiveMeasureMapper.class); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDto.java new file mode 100644 index 00000000000..b8b9d78aa49 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureDto.java @@ -0,0 +1,141 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.measure; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; + +public class LiveMeasureDto { + + private static final int MAX_TEXT_VALUE_LENGTH = 4000; + + private String componentUuid; + private String projectUuid; + private int metricId; + @Nullable + private Double value; + @Nullable + private String textValue; + @Nullable + private byte[] data; + @Nullable + private Double variation; + + public String getComponentUuid() { + return componentUuid; + } + + public LiveMeasureDto setComponentUuid(String s) { + this.componentUuid = s; + return this; + } + + public String getProjectUuid() { + return projectUuid; + } + + public LiveMeasureDto setProjectUuid(String s) { + this.projectUuid = s; + return this; + } + + public int getMetricId() { + return metricId; + } + + public LiveMeasureDto setMetricId(int i) { + this.metricId = i; + return this; + } + + @CheckForNull + public Double getValue() { + return value; + } + + public LiveMeasureDto setValue(@Nullable Double value) { + this.value = value; + return this; + } + + @CheckForNull + public String getTextValue() { + return textValue; + } + + @CheckForNull + public byte[] getData() { + return data; + } + + @CheckForNull + public String getDataAsString() { + if (data != null) { + return new String(data, StandardCharsets.UTF_8); + } + return textValue; + } + + public LiveMeasureDto setData(@Nullable String data) { + if (data == null) { + this.textValue = null; + this.data = null; + } else if (data.length() > MAX_TEXT_VALUE_LENGTH) { + this.textValue = null; + this.data = data.getBytes(StandardCharsets.UTF_8); + } else { + this.textValue = data; + this.data = null; + } + return this; + } + + public LiveMeasureDto setData(@Nullable byte[] data) { + this.textValue = null; + this.data = data; + return this; + } + + @CheckForNull + public Double getVariation() { + return variation; + } + + public LiveMeasureDto setVariation(@Nullable Double variation) { + this.variation = variation; + return this; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("LiveMeasureDto{"); + sb.append("componentUuid='").append(componentUuid).append('\''); + sb.append(", projectUuid='").append(projectUuid).append('\''); + sb.append(", metricId=").append(metricId); + sb.append(", value=").append(value); + sb.append(", variation=").append(variation); + sb.append(", textValue='").append(textValue).append('\''); + sb.append(", data=").append(Arrays.toString(data)); + sb.append('}'); + return sb.toString(); + } +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java new file mode 100644 index 00000000000..4cdfa215381 --- /dev/null +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/LiveMeasureMapper.java @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.measure; + +import java.util.Collection; +import java.util.List; +import javax.annotation.Nullable; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.session.ResultHandler; + +public interface LiveMeasureMapper { + + List<LiveMeasureDto> selectByComponentUuidsAndMetricIds( + @Param("componentUuids") List<String> componentUuids, + @Param("metricIds") Collection<Integer> metricIds); + + List<LiveMeasureDto> selectByComponentUuidsAndMetricKeys( + @Param("componentUuids") List<String> componentUuids, + @Param("metricKeys") Collection<String> metricKeys); + + void selectTreeByQuery( + @Param("query") MeasureTreeQuery measureQuery, + @Param("baseUuid") String baseUuid, + @Param("baseUuidPath") String baseUuidPath, + ResultHandler<LiveMeasureDto> resultHandler); + + void insert( + @Param("dto") LiveMeasureDto dto, + @Param("uuid") String uuid, + @Nullable @Param("marker") String marker, + @Param("now") long now); + + int update( + @Param("dto") LiveMeasureDto dto, + @Nullable @Param("marker") String marker, + @Param("now") long now); + + void deleteByProjectUuidExcludingMarker( + @Param("projectUuid") String projectUuid, + @Param("marker") String marker); +} diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java index 1656c3229a2..f6ba91fde59 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java @@ -19,24 +19,24 @@ */ package org.sonar.db.measure; -import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import java.util.Collection; import java.util.List; import java.util.Optional; -import org.apache.ibatis.session.ResultHandler; import org.sonar.db.Dao; import org.sonar.db.DbSession; -import org.sonar.db.component.ComponentDto; import static java.util.Collections.emptyList; import static org.sonar.db.DatabaseUtils.executeLargeInputs; public class MeasureDao implements Dao { - public Optional<MeasureDto> selectSingle(DbSession dbSession, MeasureQuery query) { - List<MeasureDto> measures = selectByQuery(dbSession, query); - return Optional.ofNullable(Iterables.getOnlyElement(measures, null)); + public Optional<MeasureDto> selectLastMeasure(DbSession dbSession, String componentUuid, String metricKey) { + return Optional.ofNullable(mapper(dbSession).selectLastMeasure(componentUuid, metricKey)); + } + + public Optional<MeasureDto> selectMeasure(DbSession dbSession, String analysisUuid, String componentUuid, String metricKey) { + return Optional.ofNullable(mapper(dbSession).selectMeasure(analysisUuid, componentUuid, metricKey)); } /** @@ -47,10 +47,6 @@ public class MeasureDao implements Dao { * - A list of components in {@link MeasureQuery#componentUuids} with one mandatory project in {@link MeasureQuery#projectUuids} * - One single component in {@link MeasureQuery#componentUuids} * <p> - * In addition, this method returns measures which are not associated to any developer, unless one is specified in - * {@link MeasureQuery#personId}. - * </p> - * <p> * Returned measure can optionally be filtered metric (either by specifying {@link MeasureQuery#metricIds} * or {@link MeasureQuery#metricKeys}). * </p> @@ -78,13 +74,6 @@ public class MeasureDao implements Dao { return mapper(dbSession).selectByQueryOnSingleComponent(query); } - public void selectTreeByQuery(DbSession dbSession, ComponentDto baseComponent, MeasureTreeQuery query, ResultHandler<MeasureDto> resultHandler) { - if (query.returnsEmpty()) { - return; - } - mapper(dbSession).selectTreeByQuery(query, baseComponent.uuid(), query.getUuidPath(baseComponent), resultHandler); - } - public List<PastMeasureDto> selectPastMeasures(DbSession dbSession, String componentUuid, String analysisUuid, Collection<Integer> metricIds) { if (metricIds.isEmpty()) { return emptyList(); @@ -107,19 +96,6 @@ public class MeasureDao implements Dao { return mapper(dbSession).selectPastMeasuresOnSeveralAnalyses(query); } - /** - * Used by developer cockpit. - */ - public List<MeasureDto> selectProjectMeasuresOfDeveloper(DbSession dbSession, long developerId, Collection<Integer> metricIds) { - return executeLargeInputs( - metricIds, - ids -> mapper(dbSession).selectProjectMeasuresOfDeveloper(developerId, metricIds)); - } - - public List<MeasureDto> selectByComponentsAndMetrics(DbSession dbSession, Collection<String> componentUuids, Collection<Integer> metricIds) { - return executeLargeInputs(componentUuids, partitionComponentUuids -> mapper(dbSession).selectByComponentsAndMetrics(partitionComponentUuids, metricIds)); - } - public void insert(DbSession session, MeasureDto measureDto) { mapper(session).insert(measureDto); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java index fbf5fae3594..d5161b1a117 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDto.java @@ -36,7 +36,6 @@ public class MeasureDto { private String componentUuid; private String analysisUuid; private int metricId; - private Long developerId; @CheckForNull public Double getValue() { @@ -128,16 +127,6 @@ public class MeasureDto { return this; } - @CheckForNull - public Long getDeveloperId() { - return developerId; - } - - public MeasureDto setDeveloperId(@Nullable Long developerId) { - this.developerId = developerId; - return this; - } - @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -150,7 +139,6 @@ public class MeasureDto { .add("componentUuid", componentUuid) .add("analysisUuid", analysisUuid) .add("metricId", metricId) - .add("developerId", developerId) .toString(); } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java index 4250ac4f067..c059728466e 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java @@ -19,31 +19,35 @@ */ package org.sonar.db.measure; -import java.util.Collection; import java.util.List; +import javax.annotation.CheckForNull; import org.apache.ibatis.annotations.Param; -import org.apache.ibatis.session.ResultHandler; public interface MeasureMapper { + @CheckForNull + MeasureDto selectLastMeasure( + @Param("componentUuid") String componentUuid, + @Param("metricKey") String metricKey + ); + + @CheckForNull + MeasureDto selectMeasure( + @Param("analysisUuid") String analysisUuid, + @Param("componentUuid") String componentUuid, + @Param("metricKey") String metricKey + ); + List<MeasureDto> selectByQueryOnProjects(@Param("query") MeasureQuery query); List<MeasureDto> selectByQueryOnComponents(@Param("query") MeasureQuery query); List<MeasureDto> selectByQueryOnSingleComponent(@Param("query") MeasureQuery query); - void selectTreeByQuery(@Param("query") MeasureTreeQuery measureQuery, @Param("baseUuid") String baseUuid, @Param("baseUuidPath") String baseUuidPath, - ResultHandler<MeasureDto> resultHandler); - - List<PastMeasureDto> selectPastMeasuresOnSingleAnalysis(@Param("componentUuid") String componentUuid, @Param("analysisUuid") String analysisUuid, @Param("metricIds") List<Integer> metricIds); List<MeasureDto> selectPastMeasuresOnSeveralAnalyses(@Param("query") PastMeasureQuery query); - List<MeasureDto> selectProjectMeasuresOfDeveloper(@Param("developerId") long developerId, @Param("metricIds") Collection<Integer> metricIds); - - List<MeasureDto> selectByComponentsAndMetrics(@Param("componentUuids") List<String> componentUuids, @Param("metricIds") Collection<Integer> metricIds); - void insert(MeasureDto measureDto); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java index 0b2685ebbe5..5d074d93da7 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureQuery.java @@ -44,19 +44,15 @@ public class MeasureQuery { @CheckForNull private final Collection<String> metricKeys; - @CheckForNull - private final Long personId; - private MeasureQuery(Builder builder) { - this(builder.analysisUuid, builder.projectUuids, builder.componentUuids, builder.metricIds, builder.metricKeys, builder.personId); + this(builder.analysisUuid, builder.projectUuids, builder.componentUuids, builder.metricIds, builder.metricKeys); } private MeasureQuery(@Nullable String analysisUuid, @Nullable Collection<String> projectUuids, @Nullable Collection<String> componentUuids, @Nullable Collection<Integer> metricIds, - @Nullable Collection<String> metricKeys, - @Nullable Long personId) { + @Nullable Collection<String> metricKeys) { checkArgument(metricIds == null || metricKeys == null, "Metric IDs and keys must not be set both"); checkArgument(projectUuids != null || componentUuids != null, "At least one filter on component UUID is expected"); checkArgument(componentUuids == null || componentUuids.size() == 1 || (projectUuids != null && projectUuids.size() == 1), @@ -67,7 +63,6 @@ public class MeasureQuery { this.componentUuids = componentUuids; this.metricIds = metricIds; this.metricKeys = metricKeys; - this.personId = personId; } public String getAnalysisUuid() { @@ -104,11 +99,6 @@ public class MeasureQuery { return metricKeys; } - @CheckForNull - public Long getPersonId() { - return personId; - } - public boolean returnsEmpty() { return (projectUuids != null && projectUuids.isEmpty()) || (componentUuids != null && componentUuids.isEmpty()) @@ -141,13 +131,12 @@ public class MeasureQuery { Objects.equals(projectUuids, that.projectUuids) && Objects.equals(componentUuids, that.componentUuids) && Objects.equals(metricIds, that.metricIds) && - Objects.equals(metricKeys, that.metricKeys) && - Objects.equals(personId, that.personId); + Objects.equals(metricKeys, that.metricKeys); } @Override public int hashCode() { - return Objects.hash(analysisUuid, componentUuids, metricIds, metricKeys, personId); + return Objects.hash(analysisUuid, componentUuids, metricIds, metricKeys); } public static Builder builder() { @@ -155,11 +144,11 @@ public class MeasureQuery { } static MeasureQuery copyWithSubsetOfProjectUuids(MeasureQuery query, Collection<String> projectUuids) { - return new MeasureQuery(query.analysisUuid, projectUuids, query.componentUuids, query.metricIds, query.metricKeys, query.personId); + return new MeasureQuery(query.analysisUuid, projectUuids, query.componentUuids, query.metricIds, query.metricKeys); } static MeasureQuery copyWithSubsetOfComponentUuids(MeasureQuery query, Collection<String> componentUuids) { - return new MeasureQuery(query.analysisUuid, query.projectUuids, componentUuids, query.metricIds, query.metricKeys, query.personId); + return new MeasureQuery(query.analysisUuid, query.projectUuids, componentUuids, query.metricIds, query.metricKeys); } public static final class Builder { @@ -168,7 +157,6 @@ public class MeasureQuery { private Collection<String> componentUuids; private Collection<Integer> metricIds; private Collection<String> metricKeys; - private Long personId; private Builder() { // see MeasureQuery#builder() @@ -230,11 +218,6 @@ public class MeasureQuery { return this; } - public Builder setPersonId(@Nullable Long l) { - this.personId = l; - return this; - } - public MeasureQuery build() { return new MeasureQuery(this); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureTreeQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureTreeQuery.java index 04df1a38f17..0f368911b78 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureTreeQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureTreeQuery.java @@ -47,15 +47,11 @@ public class MeasureTreeQuery { @CheckForNull private final Collection<Integer> metricIds; - @CheckForNull - private final Long personId; - private MeasureTreeQuery(Builder builder) { this.nameOrKeyQuery = builder.nameOrKeyQuery; this.qualifiers = builder.qualifiers == null ? null : newArrayList(builder.qualifiers); this.strategy = requireNonNull(builder.strategy); this.metricIds = builder.metricIds; - this.personId = builder.personId; } @CheckForNull @@ -85,11 +81,6 @@ public class MeasureTreeQuery { return metricIds; } - @CheckForNull - public Long getPersonId() { - return personId; - } - public String getUuidPath(ComponentDto component) { switch (strategy) { case CHILDREN: @@ -120,9 +111,6 @@ public class MeasureTreeQuery { @CheckForNull private Collection<Integer> metricIds; - @CheckForNull - private Long personId; - private Builder() { } @@ -149,11 +137,6 @@ public class MeasureTreeQuery { return this; } - public Builder setPersonId(@Nullable Long personId) { - this.personId = personId; - return this; - } - public MeasureTreeQuery build() { return new MeasureTreeQuery(this); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java index 0e5ccfb91aa..324c24a29ff 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/measure/PastMeasureDto.java @@ -31,9 +31,6 @@ public class PastMeasureDto { @CheckForNull private Double value; - @CheckForNull - private Long personId; - public double getValue() { requireNonNull(value); return value; @@ -56,15 +53,4 @@ public class PastMeasureDto { this.metricId = i; return this; } - - @CheckForNull - public Long getPersonId() { - return personId; - } - - PastMeasureDto setPersonId(@Nullable Long l) { - this.personId = l; - return this; - } - } 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 d6cd39815a9..b922e5a9ba2 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,24 +69,23 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea CoreMetrics.NEW_LINES_KEY, CoreMetrics.NEW_RELIABILITY_RATING_KEY); - private static final String SQL_PROJECTS = "SELECT p.organization_uuid, p.uuid, p.kee, p.name, s.uuid, s.created_at, p.tags " + + private static final String SQL_PROJECTS = "SELECT p.organization_uuid, p.uuid, p.kee, p.name, s.created_at, p.tags " + "FROM projects p " + "LEFT OUTER JOIN snapshots s ON s.component_uuid=p.uuid AND s.islast=? " + "WHERE p.enabled=? AND p.scope=? AND p.qualifier=? and p.main_branch_project_uuid is null "; private static final String PROJECT_FILTER = " AND p.uuid=?"; - private static final String SQL_MEASURES = "SELECT m.name, pm.value, pm.variation_value_1, pm.text_value FROM project_measures pm " + + private static final String SQL_MEASURES = "SELECT m.name, pm.value, pm.variation, pm.text_value FROM live_measures pm " + "INNER JOIN metrics m ON m.id = pm.metric_id " + - "WHERE pm.component_uuid = ? AND pm.analysis_uuid = ? " + + "WHERE pm.component_uuid = ? " + "AND m.name IN ({metricNames}) " + - "AND (pm.value IS NOT NULL OR pm.variation_value_1 IS NOT NULL OR pm.text_value IS NOT NULL) " + - "AND pm.person_id IS NULL " + + "AND (pm.value IS NOT NULL OR pm.variation IS NOT NULL OR pm.text_value IS NOT NULL) " + "AND m.enabled = ? "; private static final boolean ENABLED = true; private static final int FIELD_METRIC_NAME = 1; private static final int FIELD_MEASURE_VALUE = 2; - private static final int FIELD_MEASURE_VARIATION_VALUE_1 = 3; + private static final int FIELD_MEASURE_VARIATION = 3; private static final int FIELD_MEASURE_TEXT_VALUE = 4; private final PreparedStatement measuresStatement; @@ -116,10 +115,9 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea String uuid = rs.getString(2); String key = rs.getString(3); String name = rs.getString(4); - String analysisUuid = DatabaseUtils.getString(rs, 5); - Long analysisDate = DatabaseUtils.getLong(rs, 6); - List<String> tags = readDbTags(DatabaseUtils.getString(rs, 7)); - Project project = new Project(orgUuid, uuid, key, name, tags, analysisUuid, analysisDate); + Long analysisDate = DatabaseUtils.getLong(rs, 5); + List<String> tags = readDbTags(DatabaseUtils.getString(rs, 6)); + Project project = new Project(orgUuid, uuid, key, name, tags, analysisDate); projects.add(project); } return projects; @@ -165,20 +163,16 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea return null; } Project project = projects.next(); - Measures measures = selectMeasures(project.getUuid(), project.getAnalysisUuid()); + Measures measures = selectMeasures(project.getUuid()); return new ProjectMeasures(project, measures); } - private Measures selectMeasures(String projectUuid, @Nullable String analysisUuid) { + private Measures selectMeasures(String projectUuid) { Measures measures = new Measures(); - if (analysisUuid == null) { - return measures; - } ResultSet rs = null; try { AtomicInteger index = new AtomicInteger(1); measuresStatement.setString(index.getAndIncrement(), projectUuid); - measuresStatement.setString(index.getAndIncrement(), analysisUuid); METRIC_KEYS.forEach(DatabaseUtils.setStrings(measuresStatement, index::getAndIncrement)); measuresStatement.setBoolean(index.getAndIncrement(), ENABLED); rs = measuresStatement.executeQuery(); @@ -187,7 +181,7 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea } return measures; } catch (Exception e) { - throw new IllegalStateException(String.format("Fail to execute request to select measures of project %s, analysis %s", projectUuid, analysisUuid), e); + throw new IllegalStateException(String.format("Fail to execute request to select measures of project %s", projectUuid), e); } finally { DatabaseUtils.closeQuietly(rs); } @@ -195,7 +189,7 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea private static void readMeasure(ResultSet rs, Measures measures) throws SQLException { String metricKey = rs.getString(FIELD_METRIC_NAME); - Optional<Double> value = metricKey.startsWith("new_") ? getDouble(rs, FIELD_MEASURE_VARIATION_VALUE_1) : getDouble(rs, FIELD_MEASURE_VALUE); + Optional<Double> value = metricKey.startsWith("new_") ? getDouble(rs, FIELD_MEASURE_VARIATION) : getDouble(rs, FIELD_MEASURE_VALUE); if (value.isPresent()) { measures.addNumericMeasure(metricKey, value.get()); return; @@ -239,17 +233,15 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea private final String uuid; private final String key; private final String name; - private final String analysisUuid; private final Long analysisDate; private final List<String> tags; - public Project(String organizationUuid, String uuid, String key, String name, List<String> tags, @Nullable String analysisUuid, @Nullable Long analysisDate) { + public Project(String organizationUuid, String uuid, String key, String name, List<String> tags, @Nullable Long analysisDate) { this.organizationUuid = organizationUuid; this.uuid = uuid; this.key = key; this.name = name; this.tags = tags; - this.analysisUuid = analysisUuid; this.analysisDate = analysisDate; } @@ -274,11 +266,6 @@ public class ProjectMeasuresIndexerIterator extends CloseableIterator<ProjectMea } @CheckForNull - public String getAnalysisUuid() { - return analysisUuid; - } - - @CheckForNull public Long getAnalysisDate() { return analysisDate; } 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 9d65a9834c8..4ea14787571 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 @@ -21,13 +21,11 @@ package org.sonar.db.purge; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.Lists; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import org.sonar.db.DbSession; -import static com.google.common.collect.FluentIterable.from; -import static java.util.Arrays.asList; - class PurgeCommands { private static final int MAX_SNAPSHOTS_PER_QUERY = 1000; @@ -56,14 +54,14 @@ class PurgeCommands { return purgeMapper.selectAnalysisIdsAndUuids(query); } - void deleteAnalyses(String rootUuid) { + void deleteAnalyses(String rootComponentUuid) { profiler.start("deleteAnalyses (events)"); - purgeMapper.deleteEventsByComponentUuid(rootUuid); + purgeMapper.deleteEventsByComponentUuid(rootComponentUuid); session.commit(); profiler.stop(); - List<List<String>> analysisUuidsPartitions = Lists.partition(IdUuidPairs.uuids(purgeMapper.selectAnalysisIdsAndUuids(new PurgeSnapshotQuery().setComponentUuid(rootUuid))), - MAX_SNAPSHOTS_PER_QUERY); + List<List<String>> analysisUuidsPartitions = Lists.partition(IdUuidPairs.uuids( + purgeMapper.selectAnalysisIdsAndUuids(new PurgeSnapshotQuery().setComponentUuid(rootComponentUuid))), MAX_SNAPSHOTS_PER_QUERY); deleteAnalysisDuplications(analysisUuidsPartitions); @@ -84,9 +82,10 @@ class PurgeCommands { } void deleteAnalyses(PurgeSnapshotQuery... queries) { - List<IdUuidPair> snapshotIds = from(asList(queries)) - .transformAndConcat(purgeMapper::selectAnalysisIdsAndUuids) - .toList(); + List<IdUuidPair> snapshotIds = Arrays.stream(queries) + .flatMap(q -> purgeMapper.selectAnalysisIdsAndUuids(q).stream()) + .collect(Collectors.toList()); + deleteAnalyses(snapshotIds); } @@ -124,9 +123,11 @@ class PurgeCommands { profiler.start("deleteSnapshotWastedMeasures (project_measures)"); List<Long> metricIdsWithoutHistoricalData = purgeMapper.selectMetricIdsWithoutHistoricalData(); - analysisUuidsPartitions - .forEach(analysisUuidsPartition -> purgeMapper.deleteAnalysisWastedMeasures(analysisUuidsPartition, metricIdsWithoutHistoricalData)); - session.commit(); + if (!metricIdsWithoutHistoricalData.isEmpty()) { + analysisUuidsPartitions + .forEach(analysisUuidsPartition -> purgeMapper.deleteAnalysisWastedMeasures(analysisUuidsPartition, metricIdsWithoutHistoricalData)); + session.commit(); + } profiler.stop(); profiler.start("updatePurgeStatusToOne (snapshots)"); @@ -272,4 +273,11 @@ class PurgeCommands { session.commit(); profiler.stop(); } + + void deleteLiveMeasures(String rootUuid) { + profiler.start("deleteLiveMeasures (live_measures)"); + purgeMapper.deleteLiveMeasuresByProjectUuid(rootUuid); + session.commit(); + profiler.stop(); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeConfiguration.java b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeConfiguration.java index c9d903f883f..245c23c7c6a 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeConfiguration.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeConfiguration.java @@ -49,12 +49,12 @@ public class PurgeConfiguration { this.maxAgeInDaysOfInactiveShortLivingBranches = maxAgeInDaysOfInactiveShortLivingBranches; } - public static PurgeConfiguration newDefaultPurgeConfiguration(Configuration config, IdUuidPair idUuidPair, Collection<String> disabledComponentUuids) { + public static PurgeConfiguration newDefaultPurgeConfiguration(Configuration config, IdUuidPair rootId, Collection<String> disabledComponentUuids) { String[] scopes = new String[] {Scopes.FILE}; if (config.getBoolean(PurgeConstants.PROPERTY_CLEAN_DIRECTORY).orElse(false)) { scopes = new String[] {Scopes.DIRECTORY, Scopes.FILE}; } - return new PurgeConfiguration(idUuidPair, scopes, config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES).get(), + return new PurgeConfiguration(rootId, scopes, config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_CLOSED_ISSUES).get(), config.getInt(PurgeConstants.DAYS_BEFORE_DELETING_INACTIVE_SHORT_LIVING_BRANCHES), System2.INSTANCE, disabledComponentUuids); } 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 de29166e268..cad8376dc39 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 @@ -204,6 +204,7 @@ public class PurgeDao implements Dao { commands.deleteCeQueue(rootUuid); commands.deleteWebhookDeliveries(rootUuid); commands.deleteBranch(rootUuid); + commands.deleteLiveMeasures(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 3961aa6a335..c6393dc4e86 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 @@ -97,4 +97,6 @@ public interface PurgeMapper { void deleteWebhookDeliveriesByProjectUuid(@Param("projectUuid") String projectUuid); void deleteBranchByUuid(@Param("uuid") String uuid); + + void deleteLiveMeasuresByProjectUuid(@Param("projectUuid") String projectUuid); } |