aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db/src
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-01-27 16:51:21 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-01-31 14:39:53 +0100
commitbe45c77d7b596d2afaf7d5981d13007a100faf24 (patch)
tree677e5bbfddef54e3d32255360f80667fa5fdeee8 /sonar-db/src
parent6d29fdc8541bef595d92a89d4191979ec24a6012 (diff)
downloadsonarqube-be45c77d7b596d2afaf7d5981d13007a100faf24.tar.gz
sonarqube-be45c77d7b596d2afaf7d5981d13007a100faf24.zip
SONAR-8650 add organization parameter to api/projects/ghosts
Diffstat (limited to 'sonar-db/src')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java27
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java7
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml13
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java39
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentDbTester.java16
-rw-r--r--sonar-db/src/test/resources/org/sonar/db/component/ComponentDaoTest/select_ghost_projects.xml335
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>