aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db/src/main
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@sonarsource.com>2016-11-04 11:28:44 +0100
committerJulien Lancelot <julien.lancelot@sonarsource.com>2016-11-08 11:12:51 +0100
commitb67b21e7324e78bab3876f460cfe426455b2d367 (patch)
tree940698429a5416afbe404757d1c68712892b5e53 /sonar-db/src/main
parent617497c27c42a9ce4d782d1bfa8249c3a0d94083 (diff)
downloadsonarqube-b67b21e7324e78bab3876f460cfe426455b2d367.tar.gz
sonarqube-b67b21e7324e78bab3876f460cfe426455b2d367.zip
SONAR-8089 Merge ComponentDao#selectChildren and selectDescendants
Diffstat (limited to 'sonar-db/src/main')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java64
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java8
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentTreeQuery.java42
-rw-r--r--sonar-db/src/main/java/org/sonar/db/purge/PurgeDao.java15
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml53
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