diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-11-04 11:28:44 +0100 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2016-11-08 11:12:51 +0100 |
commit | b67b21e7324e78bab3876f460cfe426455b2d367 (patch) | |
tree | 940698429a5416afbe404757d1c68712892b5e53 /sonar-db/src/main | |
parent | 617497c27c42a9ce4d782d1bfa8249c3a0d94083 (diff) | |
download | sonarqube-b67b21e7324e78bab3876f460cfe426455b2d367.tar.gz sonarqube-b67b21e7324e78bab3876f460cfe426455b2d367.zip |
SONAR-8089 Merge ComponentDao#selectChildren and selectDescendants
Diffstat (limited to 'sonar-db/src/main')
5 files changed, 63 insertions, 119 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java index fd5fe9dc652..62c4652b05d 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java @@ -34,15 +34,12 @@ import org.apache.ibatis.session.RowBounds; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; import org.sonar.db.Dao; -import org.sonar.db.DatabaseUtils; import org.sonar.db.DbSession; import org.sonar.db.RowNotFoundException; -import org.sonar.db.WildcardPosition; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Maps.newHashMapWithExpectedSize; import static java.util.Collections.emptyList; -import static org.sonar.api.utils.Paging.offset; import static org.sonar.db.DatabaseUtils.executeLargeInputs; import static org.sonar.db.DatabaseUtils.executeLargeUpdates; @@ -167,42 +164,7 @@ public class ComponentDao implements Dao { } /** - * Select the children of a base component, given by its UUID. The components that are not present in last - * analysis are ignored. - * - * An empty list is returned if the base component does not exist or if the base component is a leaf. - */ - public List<ComponentDto> selectChildren(DbSession dbSession, ComponentTreeQuery query) { - Optional<ComponentDto> componentOpt = selectByUuid(dbSession, query.getBaseUuid()); - if (!componentOpt.isPresent()) { - return emptyList(); - } - ComponentDto component = componentOpt.get(); - RowBounds rowBounds = new RowBounds(offset(query.getPage(), query.getPageSize()), query.getPageSize()); - return mapper(dbSession).selectChildren(query, uuidPathForChildrenQuery(component), rowBounds); - } - - /** - * Count the children of a base component, given by its UUID. The components that are not present in last - * analysis are ignored. - * - * Zero is returned if the base component does not exist or if the base component is a leaf. - */ - public int countChildren(DbSession dbSession, ComponentTreeQuery query) { - Optional<ComponentDto> componentOpt = selectByUuid(dbSession, query.getBaseUuid()); - if (!componentOpt.isPresent()) { - return 0; - } - ComponentDto component = componentOpt.get(); - return mapper(dbSession).countChildren(query, uuidPathForChildrenQuery(component)); - } - - private static String uuidPathForChildrenQuery(ComponentDto component) { - return component.getUuidPath() + component.uuid() + "."; - } - - /** - * Select the descendants of a base component, given by its UUID. The components that are not present in last + * Select the children or the leaves of a base component, given by its UUID. The components that are not present in last * analysis are ignored. * * An empty list is returned if the base component does not exist or if the base component is a leaf. @@ -210,30 +172,10 @@ public class ComponentDao implements Dao { public List<ComponentDto> selectDescendants(DbSession dbSession, ComponentTreeQuery query) { Optional<ComponentDto> componentOpt = selectByUuid(dbSession, query.getBaseUuid()); if (!componentOpt.isPresent()) { - return Collections.emptyList(); - } - ComponentDto component = componentOpt.get(); - RowBounds rowBounds = new RowBounds(offset(query.getPage(), query.getPageSize()), query.getPageSize()); - return mapper(dbSession).selectDescendants(query, uuidPathForDescendantsQuery(component), rowBounds); - } - - /** - * Count the descendants of a base component, given by its UUID. The components that are not present in last - * analysis are ignored. - * - * Zero is returned if the base component does not exist or if the base component is a leaf. - */ - public int countDescendants(DbSession dbSession, ComponentTreeQuery query) { - Optional<ComponentDto> componentOpt = selectByUuid(dbSession, query.getBaseUuid()); - if (!componentOpt.isPresent()) { - return 0; + return emptyList(); } ComponentDto component = componentOpt.get(); - return mapper(dbSession).countDescendants(query, uuidPathForDescendantsQuery(component)); - } - - private static String uuidPathForDescendantsQuery(ComponentDto component) { - return DatabaseUtils.buildLikeValue(component.getUuidPath() + component.uuid() + ".", WildcardPosition.AFTER); + return mapper(dbSession).selectDescendants(query, query.getUuidPath(component)); } public ComponentDto selectOrFailByKey(DbSession session, String key) { diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java index 027a67fe5a1..7e41d5c97b4 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java @@ -64,13 +64,7 @@ public interface ComponentMapper { List<ComponentDto> selectAncestors(@Param("query") ComponentTreeQuery query, @Param("baseUuidPathLike") String baseUuidPathLike); - List<ComponentDto> selectChildren(@Param("query") ComponentTreeQuery query, @Param("baseUuidPath") String baseUuidPath, RowBounds rowBounds); - - int countChildren(@Param("query") ComponentTreeQuery query, @Param("baseUuidPath") String baseUuidPath); - - List<ComponentDto> selectDescendants(@Param("query") ComponentTreeQuery query, @Param("baseUuidPathLike") String baseUuidPathLike, RowBounds rowBounds); - - int countDescendants(@Param("query") ComponentTreeQuery query, @Param("baseUuidPathLike") String baseUuidPathLike); + List<ComponentDto> selectDescendants(@Param("query") ComponentTreeQuery query, @Param("baseUuidPath") String baseUuidPath); /** * Return all project (PRJ/TRK) uuids diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentTreeQuery.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentTreeQuery.java index b987ff47928..c8f47f6cd75 100644 --- a/sonar-db/src/main/java/org/sonar/db/component/ComponentTreeQuery.java +++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentTreeQuery.java @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.sonar.db.WildcardPosition; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.collect.Lists.newArrayList; @@ -37,6 +38,11 @@ import static org.sonar.db.DatabaseUtils.buildLikeValue; import static org.sonar.db.WildcardPosition.AFTER; public class ComponentTreeQuery { + + public enum Strategy { + CHILDREN, LEAVES + } + @CheckForNull private final String nameOrKeyQuery; // SONAR-7681 a public implementation of List must be used in MyBatis - potential concurrency exceptions otherwise @@ -49,6 +55,7 @@ public class ComponentTreeQuery { private final String baseUuid; private final String sqlSort; private final String direction; + private final Strategy strategy; private ComponentTreeQuery(Builder builder) { this.nameOrKeyQuery = builder.nameOrKeyQuery; @@ -56,8 +63,9 @@ public class ComponentTreeQuery { this.page = builder.page; this.pageSize = builder.pageSize; this.baseUuid = builder.baseUuid; + this.strategy = requireNonNull(builder.strategy); this.direction = builder.asc ? "ASC" : "DESC"; - this.sqlSort = sortFieldsToSqlSort(builder.sortFields, direction); + this.sqlSort = builder.sortFields != null ? sortFieldsToSqlSort(builder.sortFields, direction) : null; } public Collection<String> getQualifiers() { @@ -74,10 +82,12 @@ public class ComponentTreeQuery { return nameOrKeyQuery == null ? null : buildLikeValue(nameOrKeyQuery, AFTER).toLowerCase(Locale.ENGLISH); } + @Deprecated public Integer getPage() { return page; } + @Deprecated public Integer getPageSize() { return pageSize; } @@ -86,18 +96,36 @@ public class ComponentTreeQuery { return baseUuid; } + public Strategy getStrategy() { + return strategy; + } + + @Deprecated public String getSqlSort() { return sqlSort; } + @Deprecated public String getDirection() { return direction; } + public String getUuidPath(ComponentDto component) { + switch (strategy) { + case CHILDREN: + return component.getUuidPath() + component.uuid() + "."; + case LEAVES: + return buildLikeValue(component.getUuidPath() + component.uuid() + ".", WildcardPosition.AFTER); + default: + throw new IllegalArgumentException("Unknown strategy : " + strategy); + } + } + public static Builder builder() { return new Builder(); } + @Deprecated private static String sortFieldsToSqlSort(List<String> sortFields, String direction) { return sortFields .stream() @@ -117,6 +145,7 @@ public class ComponentTreeQuery { private String baseUuid; private List<String> sortFields; private boolean asc = true; + private Strategy strategy; private Builder() { // private constructor @@ -124,7 +153,6 @@ public class ComponentTreeQuery { public ComponentTreeQuery build() { requireNonNull(baseUuid); - requireNonNull(sortFields); return new ComponentTreeQuery(this); } @@ -138,11 +166,13 @@ public class ComponentTreeQuery { return this; } + @Deprecated public Builder setPage(int page) { this.page = page; return this; } + @Deprecated public Builder setPageSize(int pageSize) { this.pageSize = pageSize; return this; @@ -153,18 +183,26 @@ public class ComponentTreeQuery { return this; } + public Builder setStrategy(Strategy strategy) { + this.strategy = requireNonNull(strategy); + return this; + } + + @Deprecated public Builder setSortFields(List<String> sorts) { checkArgument(sorts != null && !sorts.isEmpty()); this.sortFields = sorts; return this; } + @Deprecated public Builder setAsc(boolean asc) { this.asc = asc; return this; } } + @Deprecated private static class SortFieldToSqlSortFieldFunction implements Function<String, String> { private static final String PATTERN = "LOWER(p.%1$s) %2$s, p.%1$s %2$s"; diff --git a/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java b/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java index 0b5a2f48700..aba3ff7e704 100644 --- a/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java +++ b/sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java @@ -34,6 +34,7 @@ import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDao; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ComponentTreeQuery; +import org.sonar.db.component.ComponentTreeQuery.Strategy; import static java.util.Collections.emptyList; import static org.sonar.api.utils.DateUtils.dateToLong; @@ -45,7 +46,6 @@ import static org.sonar.db.DatabaseUtils.executeLargeInputs; public class PurgeDao implements Dao { private static final Logger LOG = Loggers.get(PurgeDao.class); private static final String[] UNPROCESSED_STATUS = new String[] {"U"}; - private static final List<String> UUID_FIELD_SORT = Collections.singletonList("uuid"); private final ComponentDao componentDao; private final System2 system2; @@ -112,9 +112,10 @@ public class PurgeDao implements Dao { List<String> componentWithoutHistoricalDataUuids = componentDao .selectDescendants( dbSession, - newComponentTreeQuery() + ComponentTreeQuery.builder() .setBaseUuid(rootUuid) .setQualifiers(Arrays.asList(scopesWithoutHistoricalData)) + .setStrategy(Strategy.LEAVES) .build()) .stream().map(ComponentDto::uuid) .collect(Collectors.toList()); @@ -122,16 +123,6 @@ public class PurgeDao implements Dao { purgeCommands.deleteComponentMeasures(analysisUuids, componentWithoutHistoricalDataUuids); } - /** - * Creates a new ComponentTreeQuery.Builder with properties that don't matter here but are mandatory populated. - */ - private static ComponentTreeQuery.Builder newComponentTreeQuery() { - return ComponentTreeQuery.builder() - .setPage(1) - .setPageSize(Integer.MAX_VALUE) - .setSortFields(UUID_FIELD_SORT); - } - private void purgeDisabledComponents(DbSession session, Collection<String> uuids, PurgeListener listener) { PurgeMapper mapper = mapper(session); executeLargeInputs(uuids, diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml index 52dd7c88206..8a3aa4973a9 100644 --- a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -331,29 +331,30 @@ order by ${query.sqlSort} </select> - <!-- "p" is children --> - <select id="selectChildren" resultType="Component"> + <select id="selectDescendants" resultType="Component"> select <include refid="componentColumns"/> - <include refid="sqlChildren"/> - order by ${query.sqlSort} + <include refid="selectDescendantsQuery"/> </select> - <select id="countChildren" resultType="int"> - select count(p.id) - <include refid="sqlChildren"/> - </select> - - <sql id="sqlChildren"> + <sql id="selectDescendantsQuery"> from projects p inner join projects base on base.project_uuid = p.project_uuid and base.uuid = #{query.baseUuid} - where - p.enabled = ${_true} - and p.uuid_path = #{baseUuidPath} - <include refid="sqlTreeFilters"/> + <where> + <choose> + <when test="query.getStrategy().name() == 'CHILDREN'"> + and p.uuid_path = #{baseUuidPath} + </when> + <otherwise> + and p.uuid_path like #{baseUuidPath} ESCAPE '/' + </otherwise> + </choose> + <include refid="selectDescendantsFilters"/> + </where> </sql> - <sql id="sqlTreeFilters"> + <sql id="selectDescendantsFilters"> + and p.enabled = ${_true} <if test="query.qualifiers != null"> and p.qualifier in <foreach collection="query.qualifiers" item="qualifier" open="(" close=")" separator=","> @@ -379,28 +380,6 @@ </if> </sql> - <!-- "p" is descendants --> - <select id="selectDescendants" resultType="Component"> - select - <include refid="componentColumns"/> - <include refid="sqlDescendants"/> - order by ${query.sqlSort} - </select> - - <select id="countDescendants" resultType="int"> - select count(p.id) - <include refid="sqlDescendants"/> - </select> - - <sql id="sqlDescendants"> - from projects p - inner join projects base on base.project_uuid=p.project_uuid and base.uuid = #{query.baseUuid} - where - p.enabled = ${_true} - and p.uuid_path like #{baseUuidPathLike} ESCAPE '/' - <include refid="sqlTreeFilters"/> - </sql> - <select id="countRootComponents" resultType="int"> select count(p.id) from projects p |