diff options
author | Teryk Bellahsene <teryk.bellahsene@sonarsource.com> | 2017-09-05 17:38:36 +0200 |
---|---|---|
committer | Stas Vilchik <stas.vilchik@sonarsource.com> | 2017-09-11 11:28:29 +0200 |
commit | 2f84511c91478521a45a606cd13a703ff4de08f4 (patch) | |
tree | 35f4f6828a6f4597cf6d5bb65d1e2ba7da536c31 /server/sonar-db-dao | |
parent | e8eff068e1d16bb343c87d0c16580dcb43cc5add (diff) | |
download | sonarqube-2f84511c91478521a45a606cd13a703ff4de08f4.tar.gz sonarqube-2f84511c91478521a45a606cd13a703ff4de08f4.zip |
SONAR-9181 WS api/projects/search search by component keys or uuids
Diffstat (limited to 'server/sonar-db-dao')
5 files changed, 121 insertions, 4 deletions
diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java index 0f1d4fb8de0..e5379b9ab91 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java @@ -51,18 +51,17 @@ import static org.sonar.db.WildcardPosition.BEFORE_AND_AFTER; public class ComponentDao implements Dao { private static List<ComponentDto> selectByQueryImpl(DbSession session, @Nullable String organizationUuid, ComponentQuery query, int offset, int limit) { - Set<Long> componentIds = query.getComponentIds(); - if (componentIds != null && componentIds.isEmpty()) { + if (query.hasEmptySetOfComponents()) { return emptyList(); } return mapper(session).selectByQuery(organizationUuid, query, new RowBounds(offset, limit)); } private static int countByQueryImpl(DbSession session, @Nullable String organizationUuid, ComponentQuery query) { - Set<Long> componentIds = query.getComponentIds(); - if (componentIds != null && componentIds.isEmpty()) { + if (query.hasEmptySetOfComponents()) { return 0; } + return mapper(session).countByQuery(organizationUuid, query); } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java index 11335fc10d2..5df9f1a2b90 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentQuery.java @@ -21,6 +21,7 @@ package org.sonar.db.component; import java.util.Locale; import java.util.Set; +import java.util.stream.Stream; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.db.WildcardPosition; @@ -35,6 +36,8 @@ public class ComponentQuery { private final String language; private final Boolean isPrivate; private final Set<Long> componentIds; + private final Set<String> componentUuids; + private final Set<String> componentKeys; private final Long analyzedBefore; private final boolean onProvisionedOnly; @@ -44,6 +47,8 @@ public class ComponentQuery { this.qualifiers = builder.qualifiers; this.language = builder.language; this.componentIds = builder.componentIds; + this.componentUuids = builder.componentUuids; + this.componentKeys = builder.componentKeys; this.isPrivate = builder.isPrivate; this.analyzedBefore = builder.analyzedBefore; this.onProvisionedOnly = builder.onProvisionedOnly; @@ -84,6 +89,16 @@ public class ComponentQuery { } @CheckForNull + public Set<String> getComponentUuids() { + return componentUuids; + } + + @CheckForNull + public Set<String> getComponentKeys() { + return componentKeys; + } + + @CheckForNull public Boolean getPrivate() { return isPrivate; } @@ -97,6 +112,11 @@ public class ComponentQuery { return onProvisionedOnly; } + boolean hasEmptySetOfComponents() { + return Stream.of(componentIds, componentKeys, componentUuids) + .anyMatch(list -> list != null && list.isEmpty()); + } + public static Builder builder() { return new Builder(); } @@ -108,6 +128,8 @@ public class ComponentQuery { private String language; private Boolean isPrivate; private Set<Long> componentIds; + private Set<String> componentUuids; + private Set<String> componentKeys; private Long analyzedBefore; private boolean onProvisionedOnly = false; @@ -139,6 +161,16 @@ public class ComponentQuery { return this; } + public Builder setComponentUuids(@Nullable Set<String> componentUuids) { + this.componentUuids = componentUuids; + return this; + } + + public Builder setComponentKeys(@Nullable Set<String> componentKeys) { + this.componentKeys = componentKeys; + return this; + } + public Builder setPrivate(@Nullable Boolean isPrivate) { this.isPrivate = isPrivate; return this; diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml index 29c5724e0ad..2f738fc26d2 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/component/ComponentMapper.xml @@ -274,6 +274,18 @@ #{componentId,jdbcType=BIGINT} </foreach> </if> + <if test="query.componentKeys!=null"> + and p.kee in + <foreach collection="query.componentKeys" item="componentKey" open="(" close=")" separator=","> + #{componentKey,jdbcType=BIGINT} + </foreach> + </if> + <if test="query.componentUuids!=null"> + and p.uuid in + <foreach collection="query.componentUuids" item="componentUuid" open="(" close=")" separator=","> + #{componentUuid,jdbcType=BIGINT} + </foreach> + </if> <if test="query.nameOrKeyQuery!=null"> and ( upper(p.name) like #{query.nameOrKeyUpperLikeQuery,jdbcType=VARCHAR} escape '/' diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java index dd3c15cbd35..2050730e8fd 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java @@ -1034,7 +1034,9 @@ public class ComponentDaoTest { @Test public void selectByQuery_on_empty_list_of_component_id() { + db.components().insertPrivateProject(); ComponentQuery dbQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT).setComponentIds(emptySet()).build(); + List<ComponentDto> result = underTest.selectByQuery(dbSession, dbQuery, 0, 10); int count = underTest.countByQuery(dbSession, dbQuery); @@ -1059,6 +1061,62 @@ public class ComponentDaoTest { } @Test + public void selectByQuery_on_empty_list_of_component_key() { + db.components().insertPrivateProject(); + ComponentQuery dbQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT).setComponentKeys(emptySet()).build(); + + List<ComponentDto> result = underTest.selectByQuery(dbSession, dbQuery, 0, 10); + int count = underTest.countByQuery(dbSession, dbQuery); + + assertThat(result).isEmpty(); + assertThat(count).isEqualTo(0); + } + + @Test + public void selectByQuery_on_component_keys() { + OrganizationDto organizationDto = db.organizations().insert(); + ComponentDto sonarqube = db.components().insertComponent(newPrivateProjectDto(organizationDto)); + ComponentDto jdk8 = db.components().insertComponent(newPrivateProjectDto(organizationDto)); + ComponentDto cLang = db.components().insertComponent(newPrivateProjectDto(organizationDto)); + ComponentQuery query = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT) + .setComponentKeys(newHashSet(sonarqube.getDbKey(), jdk8.getDbKey())).build(); + + List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10); + + assertThat(result).hasSize(2).extracting(ComponentDto::getDbKey) + .containsExactlyInAnyOrder(sonarqube.getDbKey(), jdk8.getDbKey()) + .doesNotContain(cLang.getDbKey()); + } + + @Test + public void selectByQuery_on_empty_list_of_component_uuids() { + db.components().insertPrivateProject(); + ComponentQuery dbQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT).setComponentUuids(emptySet()).build(); + + List<ComponentDto> result = underTest.selectByQuery(dbSession, dbQuery, 0, 10); + int count = underTest.countByQuery(dbSession, dbQuery); + + assertThat(result).isEmpty(); + assertThat(count).isEqualTo(0); + } + + @Test + public void selectByQuery_on_component_uuids() { + OrganizationDto organizationDto = db.organizations().insert(); + ComponentDto sonarqube = db.components().insertComponent(newPrivateProjectDto(organizationDto)); + ComponentDto jdk8 = db.components().insertComponent(newPrivateProjectDto(organizationDto)); + ComponentDto cLang = db.components().insertComponent(newPrivateProjectDto(organizationDto)); + ComponentQuery query = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT) + .setComponentUuids(newHashSet(sonarqube.uuid(), jdk8.uuid())).build(); + + List<ComponentDto> result = underTest.selectByQuery(dbSession, query, 0, 10); + + assertThat(result).hasSize(2).extracting(ComponentDto::uuid) + .containsOnlyOnce(sonarqube.uuid(), jdk8.uuid()) + .doesNotContain(cLang.uuid()); + } + + @Test public void selectAncestors() { // organization OrganizationDto organization = db.organizations().insert(); diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentQueryTest.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentQueryTest.java index 018cec3f8b6..58ab4021705 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentQueryTest.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentQueryTest.java @@ -19,10 +19,13 @@ */ package org.sonar.db.component; +import java.util.function.Supplier; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import static java.util.Collections.emptySet; +import static java.util.Collections.singleton; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.api.resources.Qualifiers.PROJECT; @@ -46,6 +49,7 @@ public class ComponentQueryTest { assertThat(underTest.getAnalyzedBefore()).isEqualTo(1_000_000_000L); assertThat(underTest.isOnProvisionedOnly()).isFalse(); assertThat(underTest.isPartialMatchOnKey()).isFalse(); + assertThat(underTest.hasEmptySetOfComponents()).isFalse(); } @Test @@ -70,6 +74,18 @@ public class ComponentQueryTest { } @Test + public void empty_list_of_components() { + Supplier<ComponentQuery.Builder> query = () -> ComponentQuery.builder().setQualifiers(PROJECT); + + assertThat(query.get().setComponentIds(emptySet()).build().hasEmptySetOfComponents()).isTrue(); + assertThat(query.get().setComponentKeys(emptySet()).build().hasEmptySetOfComponents()).isTrue(); + assertThat(query.get().setComponentUuids(emptySet()).build().hasEmptySetOfComponents()).isTrue(); + assertThat(query.get().setComponentIds(singleton(404L)).build().hasEmptySetOfComponents()).isFalse(); + assertThat(query.get().setComponentKeys(singleton("P1")).build().hasEmptySetOfComponents()).isFalse(); + assertThat(query.get().setComponentUuids(singleton("U1")).build().hasEmptySetOfComponents()).isFalse(); + } + + @Test public void fail_if_no_qualifier_provided() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("At least one qualifier must be provided"); |