diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-01-27 16:51:21 +0100 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-01-31 14:39:53 +0100 |
commit | be45c77d7b596d2afaf7d5981d13007a100faf24 (patch) | |
tree | 677e5bbfddef54e3d32255360f80667fa5fdeee8 /sonar-db/src | |
parent | 6d29fdc8541bef595d92a89d4191979ec24a6012 (diff) | |
download | sonarqube-be45c77d7b596d2afaf7d5981d13007a100faf24.tar.gz sonarqube-be45c77d7b596d2afaf7d5981d13007a100faf24.zip |
SONAR-8650 add organization parameter to api/projects/ghosts
Diffstat (limited to 'sonar-db/src')
6 files changed, 68 insertions, 369 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 d475e9ead20..7deb692a59a 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 @@ -41,7 +41,6 @@ import org.sonar.db.DbSession; import org.sonar.db.RowNotFoundException; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.Maps.newHashMapWithExpectedSize; import static java.util.Collections.emptyList; import static java.util.Objects.requireNonNull; import static org.apache.commons.lang.StringUtils.isBlank; @@ -263,20 +262,12 @@ public class ComponentDao implements Dao { return DatabaseUtils.buildLikeValue(textQuery.toUpperCase(Locale.ENGLISH), BEFORE_AND_AFTER); } - public List<ComponentDto> selectGhostProjects(DbSession session, int offset, int limit, @Nullable String query) { - Map<String, Object> parameters = newHashMapWithExpectedSize(2); - addProjectQualifier(parameters); - addPartialQueryParameterIfNotNull(parameters, query); - - return mapper(session).selectGhostProjects(parameters, new RowBounds(offset, limit)); + public List<ComponentDto> selectGhostProjects(DbSession session, String organizationUuid, @Nullable String query, int offset, int limit) { + return mapper(session).selectGhostProjects(organizationUuid, queryParameterFrom(query), new RowBounds(offset, limit)); } - public long countGhostProjects(DbSession session, @Nullable String query) { - Map<String, Object> parameters = newHashMapWithExpectedSize(2); - addProjectQualifier(parameters); - addPartialQueryParameterIfNotNull(parameters, query); - - return mapper(session).countGhostProjects(parameters); + public long countGhostProjects(DbSession session, String organizationUuid, @Nullable String query) { + return mapper(session).countGhostProjects(organizationUuid, queryParameterFrom(query)); } /** @@ -317,12 +308,16 @@ public class ComponentDao implements Dao { private static void addPartialQueryParameterIfNotNull(Map<String, Object> parameters, @Nullable String keyOrNameFilter) { // TODO rely on resource_index table and match exactly the key if (keyOrNameFilter != null) { - parameters.put("query", "%" + keyOrNameFilter.toUpperCase(Locale.ENGLISH) + "%"); + parameters.put("query", queryParameterFrom(keyOrNameFilter)); } } - private static void addProjectQualifier(Map<String, Object> parameters) { - parameters.put("qualifier", Qualifiers.PROJECT); + @CheckForNull + private static String queryParameterFrom(@Nullable String keyOrNameFilter) { + if (keyOrNameFilter != null) { + return "%" + keyOrNameFilter.toUpperCase(Locale.ENGLISH) + "%"; + } + return null; } public void insert(DbSession session, ComponentDto item) { 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 2cddadffbd4..23bda21a9e9 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 @@ -21,7 +21,6 @@ package org.sonar.db.component; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nullable; @@ -122,14 +121,14 @@ public interface ComponentMapper { int countProvisioned(@Param("organizationUuid") String organizationUuid, @Nullable @Param("keyOrNameLike") String keyOrNameLike, @Param("qualifiers") Set<String> qualifiers); - List<ComponentDto> selectGhostProjects(Map<String, Object> parameters, RowBounds rowBounds); + List<ComponentDto> selectGhostProjects(@Param("organizationUuid") String organizationUuid, @Nullable @Param("query") String query, RowBounds rowBounds); + + long countGhostProjects(@Param("organizationUuid") String organizationUuid, @Nullable @Param("query") String query); List<ComponentDto> selectComponentsHavingSameKeyOrderedById(String key); List<ComponentDto> selectProjectsByNameQuery(@Param("nameQuery") @Nullable String nameQuery, @Param("includeModules") boolean includeModules); - long countGhostProjects(Map<String, Object> parameters); - void selectForIndexing(@Param("projectUuid") @Nullable String projectUuid, ResultHandler handler); void insert(ComponentDto componentDto); 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 b8a97b3df49..79b19813fff 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 @@ -380,23 +380,24 @@ <select id="selectGhostProjects" parameterType="map" resultType="Component"> select distinct - <include refid="componentColumns"/> + <include refid="componentColumns"/> from projects p - <include refid="ghostClauses"/> + <include refid="ghostProjectClauses"/> </select> <select id="countGhostProjects" parameterType="map" resultType="long"> - select count(p.id) + select + count(distinct p.id) from projects p - <include refid="ghostClauses"/> + <include refid="ghostProjectClauses"/> </select> - <sql id="ghostClauses"> + <sql id="ghostProjectClauses"> inner join snapshots s1 on s1.component_uuid = p.uuid and s1.status='U' left join snapshots s2 on s2.component_uuid = p.uuid and s2.status='P' where s2.id is null - and p.qualifier=#{qualifier,jdbcType=VARCHAR} + and p.qualifier='TRK' and p.copy_component_uuid is null <if test="query!=null"> and ( 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 646a54be31a..2ac7254b0ce 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 @@ -49,6 +49,7 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.guava.api.Assertions.assertThat; import static org.sonar.db.component.ComponentTesting.newDeveloper; +import static org.sonar.db.component.ComponentTesting.newDirectory; import static org.sonar.db.component.ComponentTesting.newFileDto; import static org.sonar.db.component.ComponentTesting.newModuleDto; import static org.sonar.db.component.ComponentTesting.newProjectCopy; @@ -596,13 +597,39 @@ public class ComponentDaoTest { @Test public void select_ghost_projects() { - db.prepareDbUnit(getClass(), "select_ghost_projects.xml"); - - List<ComponentDto> result = underTest.selectGhostProjects(dbSession, 0, 10, null); + OrganizationDto organization = db.organizations().insert(); - assertThat(result).hasSize(1); - assertThat(result.get(0).key()).isEqualTo("org.ghost.project"); - assertThat(underTest.countGhostProjects(dbSession, null)).isEqualTo(1); + // ghosts because has at least one snapshot with status U but none with status P + ComponentDto ghostProject = db.components().insertProject(organization); + db.components().insertSnapshot(ghostProject, dto -> dto.setStatus("U")); + db.components().insertSnapshot(ghostProject, dto -> dto.setStatus("U")); + ComponentDto ghostProject2 = db.components().insertProject(organization); + db.components().insertSnapshot(ghostProject2, dto -> dto.setStatus("U")); + ComponentDto disabledGhostProject = db.components().insertProject(dto -> dto.setEnabled(false)); + db.components().insertSnapshot(disabledGhostProject, dto -> dto.setStatus("U")); + + ComponentDto project1 = db.components().insertProject(organization); + db.components().insertSnapshot(project1, dto -> dto.setStatus("P")); + db.components().insertSnapshot(project1, dto -> dto.setStatus("U")); + ComponentDto module = db.components().insertComponent(newModuleDto(project1)); + ComponentDto dir = db.components().insertComponent(newDirectory(module, "foo")); + db.components().insertComponent(newFileDto(module, dir, "bar")); + + ComponentDto provisionedProject = db.components().insertProject(organization); + + // not a ghost because has at least one snapshot with status P + ComponentDto project2 = db.components().insertProject(organization); + db.components().insertSnapshot(project2, dto -> dto.setStatus("P")); + + // not a ghost because it's not a project + ComponentDto view = db.components().insertView(organization); + db.components().insertSnapshot(view, dto -> dto.setStatus("U")); + db.components().insertComponent(newProjectCopy("do", project1, view)); + + assertThat(underTest.selectGhostProjects(dbSession, organization.getUuid(), null, 0, 10)) + .extracting(ComponentDto::uuid) + .containsOnly(ghostProject.uuid(), ghostProject2.uuid(), disabledGhostProject.uuid()); + assertThat(underTest.countGhostProjects(dbSession, organization.getUuid(), null)).isEqualTo(3); } @Test diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java index 67d438cb847..d8f93680b66 100644 --- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java +++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java @@ -95,7 +95,7 @@ public class ComponentDbTester { } public ComponentDto insertView(OrganizationDto organizationDto) { - return insertComponentImpl(newView(organizationDto), dto -> {}); + return insertComponentImpl(newView(organizationDto), noExtraConfiguration()); } public ComponentDto insertView(OrganizationDto organizationDto, Consumer<ComponentDto> dtoPopulator) { @@ -111,7 +111,7 @@ public class ComponentDbTester { } public ComponentDto insertDeveloper(String name, Consumer<ComponentDto> dtoPopulator) { - return insertComponentImpl(newDeveloper(db.getDefaultOrganization(), name), noExtraConfiguration()); + return insertComponentImpl(newDeveloper(db.getDefaultOrganization(), name), dtoPopulator); } public ComponentDto insertDeveloper(String name) { @@ -145,4 +145,16 @@ public class ComponentDbTester { db.commit(); return snapshot; } + + public SnapshotDto insertSnapshot(ComponentDto componentDto) { + return insertSnapshot(componentDto, noExtraConfiguration()); + } + + public SnapshotDto insertSnapshot(ComponentDto componentDto, Consumer<SnapshotDto> consumer) { + SnapshotDto snapshotDto = SnapshotTesting.newAnalysis(componentDto); + consumer.accept(snapshotDto); + SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, snapshotDto); + db.commit(); + return snapshot; + } } diff --git a/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/select_ghost_projects.xml b/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/select_ghost_projects.xml deleted file mode 100644 index f5ad3efa9c2..00000000000 --- a/sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/select_ghost_projects.xml +++ /dev/null @@ -1,335 +0,0 @@ -<dataset> - - <!-- Struts projects is authorized for all user --> - <group_roles id="1" - group_id="[null]" - resource_id="1" - role="user" - organization_uuid="org1"/> - - <!-- Ghost project --> - <projects organization_uuid="org1" - id="42" - root_uuid="PPAA" - scope="PRJ" - qualifier="TRK" - kee="org.ghost.project" - name="Ghost Project" - uuid="PPAA" - uuid_path="NOT_USED" - project_uuid="PPAA" - module_uuid="[null]" - module_uuid_path="." - description="the description" - long_name="Ghost Project" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="[null]" - authorization_updated_at="123456789"/> - - <!-- root project --> - <projects organization_uuid="org1" - id="1" - root_uuid="ABCD" - scope="PRJ" - qualifier="TRK" - kee="org.struts:struts" - deprecated_kee="org.struts:struts" - name="Struts" - uuid="ABCD" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="[null]" - module_uuid_path=".ABCD." - description="the description" - long_name="Apache Struts" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="[null]" - authorization_updated_at="123456789"/> - <snapshots id="1" - uuid="u1" - component_uuid="ABCD" - status="P" - islast="[true]" - purge_status="[null]" - period1_mode="[null]" - period1_param="[null]" - period1_date="[null]" - period2_mode="[null]" - period2_param="[null]" - period2_date="[null]" - period3_mode="[null]" - period3_param="[null]" - period3_date="[null]" - period4_mode="[null]" - period4_param="[null]" - period4_date="[null]" - period5_mode="[null]" - period5_param="[null]" - period5_date="[null]" - created_at="1228222680000" - build_date="1228222680000" - version="[null]" - /> - <snapshots id="10" - uuid="u10" - component_uuid="ABCD" - status="P" - islast="[false]" - purge_status="[null]" - period1_mode="[null]" - period1_param="[null]" - period1_date="[null]" - period2_mode="[null]" - period2_param="[null]" - period2_date="[null]" - period3_mode="[null]" - period3_param="[null]" - period3_date="[null]" - period4_mode="[null]" - period4_param="[null]" - period4_date="[null]" - period5_mode="[null]" - period5_param="[null]" - period5_date="[null]" - created_at="1228136280000" - build_date="1228136280000" - version="[null]" - /> - <snapshots id="11" - uuid="u11" - component_uuid="PPAA" - status="U" - islast="[false]" - purge_status="[null]" - period1_mode="[null]" - period1_param="[null]" - period1_date="[null]" - period2_mode="[null]" - period2_param="[null]" - period2_date="[null]" - period3_mode="[null]" - period3_param="[null]" - period3_date="[null]" - period4_mode="[null]" - period4_param="[null]" - period4_date="[null]" - period5_mode="[null]" - period5_param="[null]" - period5_date="[null]" - created_at="1228136280000" - build_date="1228136280000" - version="[null]" - /> - - <!-- module --> - <projects organization_uuid="org1" - id="2" - root_uuid="ABCD" - kee="org.struts:struts-core" - name="Struts Core" - uuid="EFGH" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="[null]" - module_uuid_path=".ABCD.EFGH." - scope="PRJ" - qualifier="BRC" - long_name="Struts Core" - description="[null]" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - authorization_updated_at="[null]"/> - <snapshots id="2" - uuid="u2" - component_uuid="EFGH" - status="P" - islast="[true]" - purge_status="[null]" - period1_mode="[null]" - period1_param="[null]" - period1_date="[null]" - period2_mode="[null]" - period2_param="[null]" - period2_date="[null]" - period3_mode="[null]" - period3_param="[null]" - period3_date="[null]" - period4_mode="[null]" - period4_param="[null]" - period4_date="[null]" - period5_mode="[null]" - period5_param="[null]" - period5_date="[null]" - created_at="1228222680000" - build_date="1228222680000" - version="[null]" - /> - - <!-- directory --> - <projects organization_uuid="org1" - long_name="org.struts" - id="3" - scope="DIR" - qualifier="DIR" - kee="org.struts:struts-core:src/org/struts" - uuid="GHIJ" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="EFGH" - module_uuid_path=".ABCD.EFGH." - name="src/org/struts" - root_uuid="EFGH" - description="[null]" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="src/org/struts" - authorization_updated_at="[null]"/> - <snapshots id="3" - uuid="u3" - component_uuid="GHIJ" - status="P" - islast="[true]" - purge_status="[null]" - period1_mode="[null]" - period1_param="[null]" - period1_date="[null]" - period2_mode="[null]" - period2_param="[null]" - period2_date="[null]" - period3_mode="[null]" - period3_param="[null]" - period3_date="[null]" - period4_mode="[null]" - period4_param="[null]" - period4_date="[null]" - period5_mode="[null]" - period5_param="[null]" - period5_date="[null]" - created_at="1228222680000" - build_date="1228222680000" - version="[null]" - /> - - <!-- file --> - <projects organization_uuid="org1" - long_name="org.struts.RequestContext" - id="4" - scope="FIL" - qualifier="FIL" - kee="org.struts:struts-core:src/org/struts/RequestContext.java" - uuid="KLMN" - uuid_path="NOT_USED" - project_uuid="ABCD" - module_uuid="EFGH" - module_uuid_path=".ABCD.EFGH." - name="RequestContext.java" - root_uuid="EFGH" - description="[null]" - enabled="[true]" - language="java" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="src/org/struts/RequestContext.java" - authorization_updated_at="[null]"/> - - <snapshots id="4" - uuid="u4" - component_uuid="KLMN" - status="P" - islast="[true]" - purge_status="[null]" - period1_mode="[null]" - period1_param="[null]" - period1_date="[null]" - period2_mode="[null]" - period2_param="[null]" - period2_date="[null]" - period3_mode="[null]" - period3_param="[null]" - period3_date="[null]" - period4_mode="[null]" - period4_param="[null]" - period4_date="[null]" - period5_mode="[null]" - period5_param="[null]" - period5_date="[null]" - created_at="1228222680000" - build_date="1228222680000" - version="[null]" - /> - - <!-- Disabled projects --> - <projects organization_uuid="org1" - id="10" - root_uuid="DCBA" - scope="PRJ" - qualifier="TRK" - kee="org.disabled.project" - name="Disabled Project" - uuid="DCBA" - uuid_path="NOT_USED" - project_uuid="DCBA" - module_uuid="[null]" - module_uuid_path="." - description="the description" - long_name="Disabled project" - enabled="[false]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="[null]" - authorization_updated_at="123456789"/> - - <!-- Developer and technical project copy --> - <projects organization_uuid="org1" - id="11" - root_uuid="OPQR" - scope="PRJ" - qualifier="DEV" - kee="DEV:anakin@skywalker.name" - name="Anakin Skywalker" - uuid="OPQR" - uuid_path="NOT_USED" - project_uuid="OPQR" - module_uuid="[null]" - module_uuid_path=".OPQR." - description="the description" - long_name="Anakin Skywalker" - enabled="[true]" - language="[null]" - copy_component_uuid="[null]" - developer_uuid="[null]" - path="[null]" - authorization_updated_at="123456789"/> - <projects organization_uuid="org1" - id="12" - root_uuid="OPQR" - scope="PRJ" - qualifier="DEV_PRJ" - kee="DEV:anakin@skywalker.name:org.struts:struts" - name="Apache Struts" - uuid="STUV" - uuid_path="NOT_USED" - project_uuid="OPQR" - module_uuid="OPQR" - module_uuid_path=".OPQR." - description="the description" - long_name="Apache Struts" - enabled="[true]" - language="[null]" - copy_component_uuid="ABCD" - developer_uuid="OPQR" - path="[null]" - authorization_updated_at="123456789"/> - -</dataset> |