diff options
Diffstat (limited to 'sonar-db')
6 files changed, 135 insertions, 300 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 diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java index 394d2a241e9..70f3e206e23 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java @@ -47,6 +47,8 @@ import static org.sonar.db.component.ComponentTesting.newProjectCopy; import static org.sonar.db.component.ComponentTesting.newProjectDto; import static org.sonar.db.component.ComponentTesting.newSubView; import static org.sonar.db.component.ComponentTesting.newView; +import static org.sonar.db.component.ComponentTreeQuery.Strategy.CHILDREN; +import static org.sonar.db.component.ComponentTreeQuery.Strategy.LEAVES; public class ComponentDaoTest { @@ -677,8 +679,7 @@ public class ComponentDaoTest { .setBModuleUuidPath("moduleUuidPath") .setBName("name") .setBPath("path") - .setBQualifier("qualifier") - ); + .setBQualifier("qualifier")); dbSession.commit(); Map<String, Object> row = selectBColumnsForUuid("U1"); @@ -840,7 +841,47 @@ public class ComponentDaoTest { } @Test - public void selectChildren() { + public void selectParent() { + // project -> module -> file + ComponentDto project = newProjectDto(PROJECT_UUID); + componentDb.insertProjectAndSnapshot(project); + ComponentDto module = newModuleDto(MODULE_UUID, project); + componentDb.insertComponent(module); + ComponentDto file = newFileDto(module, null, FILE_1_UUID); + componentDb.insertComponent(file); + db.commit(); + + assertThat(underTest.selectParent(dbSession, project)).isAbsent(); + assertThat(underTest.selectParent(dbSession, module).get().uuid()).isEqualTo(PROJECT_UUID); + assertThat(underTest.selectParent(dbSession, file).get().uuid()).isEqualTo(MODULE_UUID); + } + + @Test + public void selectAncestors() { + // project -> module -> file + ComponentDto project = newProjectDto(PROJECT_UUID); + componentDb.insertProjectAndSnapshot(project); + ComponentDto module = newModuleDto(MODULE_UUID, project); + componentDb.insertComponent(module); + ComponentDto file = newFileDto(module, null, FILE_1_UUID); + componentDb.insertComponent(file); + db.commit(); + + // ancestors of root + List<ComponentDto> ancestors = underTest.selectAncestors(dbSession, project); + assertThat(ancestors).isEmpty(); + + // ancestors of module + ancestors = underTest.selectAncestors(dbSession, module); + assertThat(ancestors).extracting("uuid").containsExactly(PROJECT_UUID); + + // ancestors of file + ancestors = underTest.selectAncestors(dbSession, file); + assertThat(ancestors).extracting("uuid").containsExactly(PROJECT_UUID, MODULE_UUID); + } + + @Test + public void select_descendants_with_children_stragegy() { // project has 2 children: module and file 1. Other files are part of module. ComponentDto project = newProjectDto(PROJECT_UUID); componentDb.insertProjectAndSnapshot(project); @@ -857,133 +898,81 @@ public class ComponentDaoTest { // test children of root ComponentTreeQuery query = newTreeQuery(PROJECT_UUID).build(); - List<ComponentDto> children = underTest.selectChildren(dbSession, query); - assertThat(children).extracting("uuid").containsExactly(FILE_1_UUID, MODULE_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(2); + List<ComponentDto> children = underTest.selectDescendants(dbSession, query); + assertThat(children).extracting("uuid").containsOnly(FILE_1_UUID, MODULE_UUID); // test children of root, filtered by qualifier query = newTreeQuery(PROJECT_UUID).setQualifiers(asList(Qualifiers.MODULE)).build(); - children = underTest.selectChildren(dbSession, query); - assertThat(children).extracting("uuid").containsExactly(MODULE_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(1); + children = underTest.selectDescendants(dbSession, query); + assertThat(children).extracting("uuid").containsOnly(MODULE_UUID); // test children of intermediate component (module here), default ordering by query = newTreeQuery(MODULE_UUID).build(); - assertThat(underTest.selectChildren(dbSession, query)).extracting("uuid").containsOnly(FILE_2_UUID, FILE_3_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(2); + assertThat(underTest.selectDescendants(dbSession, query)).extracting("uuid").containsOnly(FILE_2_UUID, FILE_3_UUID); // test children of leaf component (file here) query = newTreeQuery(FILE_1_UUID).build(); - assertThat(underTest.selectChildren(dbSession, query)).isEmpty(); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(0); + assertThat(underTest.selectDescendants(dbSession, query)).isEmpty(); // test children of root, matching name query = newTreeQuery(PROJECT_UUID).setNameOrKeyQuery("One").build(); - assertThat(underTest.selectChildren(dbSession, query)).extracting("uuid").containsOnly(FILE_1_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(1); + assertThat(underTest.selectDescendants(dbSession, query)).extracting("uuid").containsOnly(FILE_1_UUID); // test children of root, matching case-insensitive name query = newTreeQuery(PROJECT_UUID).setNameOrKeyQuery("OnE").build(); - assertThat(underTest.selectChildren(dbSession, query)).extracting("uuid").containsOnly(FILE_1_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(1); + assertThat(underTest.selectDescendants(dbSession, query)).extracting("uuid").containsOnly(FILE_1_UUID); // test children of root, matching key query = newTreeQuery(PROJECT_UUID).setNameOrKeyQuery("file-key-1").build(); - assertThat(underTest.selectChildren(dbSession, query)).extracting("uuid").containsOnly(FILE_1_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(1); + assertThat(underTest.selectDescendants(dbSession, query)).extracting("uuid").containsOnly(FILE_1_UUID); // test children of root, without matching name nor key query = newTreeQuery(PROJECT_UUID).setNameOrKeyQuery("does-not-exist").build(); - assertThat(underTest.selectChildren(dbSession, query)).isEmpty(); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(0); + assertThat(underTest.selectDescendants(dbSession, query)).isEmpty(); // test children of intermediate component (module here), matching name query = newTreeQuery(MODULE_UUID).setNameOrKeyQuery("Two").build(); - assertThat(underTest.selectChildren(dbSession, query)).extracting("uuid").containsOnly(FILE_2_UUID); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(1); + assertThat(underTest.selectDescendants(dbSession, query)).extracting("uuid").containsOnly(FILE_2_UUID); // test children of intermediate component (module here), without matching name query = newTreeQuery(MODULE_UUID).setNameOrKeyQuery("does-not-exist").build(); - assertThat(underTest.selectChildren(dbSession, query)).isEmpty(); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(0); + assertThat(underTest.selectDescendants(dbSession, query)).isEmpty(); // test children of leaf component (file here) query = newTreeQuery(FILE_1_UUID).build(); - assertThat(underTest.selectChildren(dbSession, query)).isEmpty(); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(0); + assertThat(underTest.selectDescendants(dbSession, query)).isEmpty(); // test children of leaf component (file here), matching name query = newTreeQuery(FILE_1_UUID).setNameOrKeyQuery("Foo").build(); - assertThat(underTest.selectChildren(dbSession, query)).isEmpty(); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(0); - } - - @Test - public void selectChildren_with_pagination() { - ComponentDto project = newProjectDto(PROJECT_UUID); - componentDb.insertProjectAndSnapshot(project); - for (int i = 1; i <= 9; i++) { - componentDb.insertComponent(newFileDto(project, null, "file-uuid-" + i)); - } - db.commit(); - - ComponentTreeQuery query = newTreeQuery(PROJECT_UUID) - .setPage(2) - .setPageSize(3) - .setAsc(false) - .build(); - - assertThat(underTest.selectChildren(dbSession, query)).extracting("uuid").containsExactly("file-uuid-6", "file-uuid-5", "file-uuid-4"); - assertThat(underTest.countChildren(dbSession, query)).isEqualTo(9); + assertThat(underTest.selectDescendants(dbSession, query)).isEmpty(); } @Test - public void selectChildren_ordered_by_file_path() { + public void select_descendants_with_leaves_stragegy() { ComponentDto project = newProjectDto(PROJECT_UUID); componentDb.insertProjectAndSnapshot(project); - componentDb.insertComponent(newFileDto(project, null, "file-uuid-1").setName("file-name-1").setPath("3")); - componentDb.insertComponent(newFileDto(project, null, "file-uuid-2").setName("file-name-2").setPath("2")); - componentDb.insertComponent(newFileDto(project, null, "file-uuid-3").setName("file-name-3").setPath("1")); + componentDb.insertComponent(newModuleDto("module-1-uuid", project)); + componentDb.insertComponent(newFileDto(project, null, "file-1-uuid")); + componentDb.insertComponent(newFileDto(project, null, "file-2-uuid")); db.commit(); componentDb.indexAllComponents(); - ComponentTreeQuery query = newTreeQuery(PROJECT_UUID) - .setSortFields(singletonList("path")) - .setAsc(true) - .build(); + ComponentTreeQuery query = newTreeQuery(PROJECT_UUID).setStrategy(LEAVES).build(); - List<ComponentDto> result = underTest.selectChildren(dbSession, query); - assertThat(result).extracting("uuid").containsExactly("file-uuid-3", "file-uuid-2", "file-uuid-1"); + List<ComponentDto> result = underTest.selectDescendants(dbSession, query); + assertThat(result).extracting("uuid").containsOnly("file-1-uuid", "file-2-uuid", "module-1-uuid"); } @Test - public void selectChildren_returns_empty_list_if_base_component_does_not_exist() { - ComponentTreeQuery query = newTreeQuery(PROJECT_UUID).build(); + public void select_descendants_returns_empty_list_if_base_component_does_not_exist() { + ComponentTreeQuery query = newTreeQuery(PROJECT_UUID).setStrategy(CHILDREN).build(); - List<ComponentDto> result = underTest.selectChildren(dbSession, query); + List<ComponentDto> result = underTest.selectDescendants(dbSession, query); assertThat(result).isEmpty(); } @Test - public void selectChildren_of_a_view() { - ComponentDto view = newView(A_VIEW_UUID); - componentDb.insertViewAndSnapshot(view); - // one subview - ComponentDto subView = newSubView(view, "subview-uuid", "subview-key").setName("subview-name"); - componentDb.insertComponent(subView); - // one project and its copy linked to the view - ComponentDto project = newProjectDto(PROJECT_UUID).setName("project-name"); - componentDb.insertProjectAndSnapshot(project); - componentDb.insertComponent(newProjectCopy("project-copy-uuid", project, view)); - componentDb.indexAllComponents(); - ComponentTreeQuery query = newTreeQuery(A_VIEW_UUID).build(); - - List<ComponentDto> components = underTest.selectChildren(dbSession, query); - assertThat(components).extracting("uuid").containsOnly("project-copy-uuid", "subview-uuid"); - } - - @Test - public void selectChildren_of_a_view_and_filter_by_name() { + public void select_descendants_of_a_view_and_filter_by_name() { ComponentDto view = newView(A_VIEW_UUID); componentDb.insertViewAndSnapshot(view); // one subview @@ -994,113 +983,15 @@ public class ComponentDaoTest { componentDb.insertProjectAndSnapshot(project); componentDb.insertComponent(newProjectCopy("project-copy-uuid", project, view)); componentDb.indexAllComponents(); - ComponentTreeQuery dbQuery = newTreeQuery(A_VIEW_UUID).setNameOrKeyQuery("name").build(); + ComponentTreeQuery dbQuery = newTreeQuery(A_VIEW_UUID).setNameOrKeyQuery("name").setStrategy(CHILDREN).build(); - List<ComponentDto> components = underTest.selectChildren(dbSession, dbQuery); + List<ComponentDto> components = underTest.selectDescendants(dbSession, dbQuery); assertThat(components).extracting("uuid").containsOnly("project-copy-uuid", "subview-uuid"); } - @Test - public void selectParent() { - // project -> module -> file - ComponentDto project = newProjectDto(PROJECT_UUID); - componentDb.insertProjectAndSnapshot(project); - ComponentDto module = newModuleDto(MODULE_UUID, project); - componentDb.insertComponent(module); - ComponentDto file = newFileDto(module, null, FILE_1_UUID); - componentDb.insertComponent(file); - db.commit(); - - assertThat(underTest.selectParent(dbSession, project)).isAbsent(); - assertThat(underTest.selectParent(dbSession, module).get().uuid()).isEqualTo(PROJECT_UUID); - assertThat(underTest.selectParent(dbSession, file).get().uuid()).isEqualTo(MODULE_UUID); - } - - @Test - public void selectAncestors() { - // project -> module -> file - ComponentDto project = newProjectDto(PROJECT_UUID); - componentDb.insertProjectAndSnapshot(project); - ComponentDto module = newModuleDto(MODULE_UUID, project); - componentDb.insertComponent(module); - ComponentDto file = newFileDto(module, null, FILE_1_UUID); - componentDb.insertComponent(file); - db.commit(); - - // ancestors of root - List<ComponentDto> ancestors = underTest.selectAncestors(dbSession, project); - assertThat(ancestors).isEmpty(); - - // ancestors of module - ancestors = underTest.selectAncestors(dbSession, module); - assertThat(ancestors).extracting("uuid").containsExactly(PROJECT_UUID); - - // ancestors of file - ancestors = underTest.selectAncestors(dbSession, file); - assertThat(ancestors).extracting("uuid").containsExactly(PROJECT_UUID, MODULE_UUID); - } - - @Test - public void selectDescendants() { - ComponentDto project = newProjectDto(PROJECT_UUID); - componentDb.insertProjectAndSnapshot(project); - componentDb.insertComponent(newModuleDto("module-1-uuid", project)); - componentDb.insertComponent(newFileDto(project, null, "file-1-uuid")); - componentDb.insertComponent(newFileDto(project, null, "file-2-uuid")); - db.commit(); - componentDb.indexAllComponents(); - - ComponentTreeQuery query = newTreeQuery(PROJECT_UUID).build(); - - List<ComponentDto> result = underTest.selectDescendants(dbSession, query); - assertThat(result).extracting("uuid").containsExactly("file-1-uuid", "file-2-uuid", "module-1-uuid"); - int count = underTest.countDescendants(dbSession, query); - assertThat(count).isEqualTo(3); - } - - @Test - public void selectDescendants_returns_empty_list_if_base_component_does_not_exist() { - ComponentTreeQuery query = newTreeQuery(PROJECT_UUID).build(); - - List<ComponentDto> result = underTest.selectDescendants(dbSession, query); - assertThat(result).isEmpty(); - } - - @Test - public void selectDescendants_of_a_project_paginated_and_ordered() { - ComponentDto project = newProjectDto(PROJECT_UUID).setKey("project-key"); - componentDb.insertProjectAndSnapshot(project); - componentDb.insertComponent(newModuleDto("module-1-uuid", project)); - componentDb.insertComponent(newFileDto(project, null, "file-uuid-1").setName("file-name-1")); - componentDb.insertComponent(newFileDto(project, null, "another-uuid")); - for (int i = 2; i <= 9; i++) { - componentDb.insertComponent(newFileDto(project, null, "file-uuid-" + i).setName("file-name-" + i)); - } - db.commit(); - componentDb.indexAllComponents(); - - ComponentTreeQuery query = newTreeQuery(PROJECT_UUID) - .setQualifiers(newArrayList(Qualifiers.FILE)) - .setPage(2) - .setPageSize(3) - .setNameOrKeyQuery("file-name") - .setSortFields(singletonList("name")) - .setAsc(false) - .build(); - - List<ComponentDto> result = underTest.selectDescendants(dbSession, query); - int count = underTest.countDescendants(dbSession, query); - - assertThat(count).isEqualTo(9); - assertThat(result).extracting("uuid").containsExactly("file-uuid-6", "file-uuid-5", "file-uuid-4"); - } - private static ComponentTreeQuery.Builder newTreeQuery(String baseUuid) { return ComponentTreeQuery.builder() - .setPage(1) - .setPageSize(500) .setBaseUuid(baseUuid) - .setSortFields(singletonList("name")) - .setAsc(true); + .setStrategy(CHILDREN); } } |