aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-01-13 16:35:16 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2017-01-16 13:01:40 +0100
commitb063b87fa456cb49cba2afde0e88bff83ecdaedc (patch)
treeebb11c98dfe5be7e87c1e856debd7686b5b983e6 /sonar-db
parente09bee5fed18be0ff8730c510ff3d72156957529 (diff)
downloadsonarqube-b063b87fa456cb49cba2afde0e88bff83ecdaedc.tar.gz
sonarqube-b063b87fa456cb49cba2afde0e88bff83ecdaedc.zip
SONAR-8613 add filter on keys to OrganizationDao.selectByQuery
Diffstat (limited to 'sonar-db')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java5
-rw-r--r--sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java3
-rw-r--r--sonar-db/src/main/java/org/sonar/db/organization/OrganizationQuery.java71
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml8
-rw-r--r--sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java147
5 files changed, 215 insertions, 19 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java
index e39a27d7157..2705c8355e4 100644
--- a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationDao.java
@@ -46,8 +46,9 @@ public class OrganizationDao implements Dao {
getMapper(dbSession).insert(organization);
}
- public List<OrganizationDto> selectByQuery(DbSession dbSession, int offset, int limit) {
- return getMapper(dbSession).selectByQuery(offset, limit);
+ public List<OrganizationDto> selectByQuery(DbSession dbSession, OrganizationQuery organizationQuery, int offset, int limit) {
+ requireNonNull(organizationQuery, "organizationQuery can't be null");
+ return getMapper(dbSession).selectByQuery(organizationQuery, offset, limit);
}
public Optional<OrganizationDto> selectByUuid(DbSession dbSession, String uuid) {
diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java
index 7da4a027413..8a2b9b3c1fb 100644
--- a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationMapper.java
@@ -26,7 +26,8 @@ import org.apache.ibatis.annotations.Param;
public interface OrganizationMapper {
void insert(@Param("organization") OrganizationDto organization);
- List<OrganizationDto> selectByQuery(@Param("offset") int offset, @Param("pageSize") int pageSize);
+ List<OrganizationDto> selectByQuery(@Param("query") OrganizationQuery organizationQuery,
+ @Param("offset") int offset, @Param("pageSize") int pageSize);
@CheckForNull
OrganizationDto selectByKey(@Param("key") String key);
diff --git a/sonar-db/src/main/java/org/sonar/db/organization/OrganizationQuery.java b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationQuery.java
new file mode 100644
index 00000000000..29967eba2b8
--- /dev/null
+++ b/sonar-db/src/main/java/org/sonar/db/organization/OrganizationQuery.java
@@ -0,0 +1,71 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.db.organization;
+
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
+
+import static org.sonar.core.util.stream.Collectors.toSet;
+
+public class OrganizationQuery {
+ private static final OrganizationQuery NO_QUERY = newOrganizationQueryBuilder().build();
+ private final Set<String> keys;
+
+ private OrganizationQuery(Builder builder) {
+ this.keys = builder.keys;
+ }
+
+ public static OrganizationQuery returnAll() {
+ return NO_QUERY;
+ }
+
+ public static Builder newOrganizationQueryBuilder() {
+ return new Builder();
+ }
+
+ @CheckForNull
+ public Set<String> getKeys() {
+ return keys;
+ }
+
+ public static class Builder {
+ private Set<String> keys;
+
+ private Builder() {
+ // use static factory method
+ }
+
+ public Builder setKeys(@Nullable Collection<String> keys) {
+ if (keys != null && !keys.isEmpty()) {
+ this.keys = keys.stream()
+ .filter(Objects::nonNull)
+ .collect(toSet(keys.size()));
+ }
+ return this;
+ }
+
+ public OrganizationQuery build() {
+ return new OrganizationQuery(this);
+ }
+ }
+}
diff --git a/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml b/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml
index e120713908c..c7ab1ea8461 100644
--- a/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/organization/OrganizationMapper.xml
@@ -75,6 +75,14 @@
<sql id="sqlSelectByQuery">
from organizations org
+ <where>
+ <if test="query.keys != null">
+ org.kee in
+ <foreach collection="query.keys" open="(" close=")" item="key" separator=",">
+ #{key, jdbcType=VARCHAR}
+ </foreach>
+ </if>
+ </where>
</sql>
<insert id="insert" parameterType="Organization" useGeneratedKeys="false">
diff --git a/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java b/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java
index 000cb53dac3..88a51f6e658 100644
--- a/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/organization/OrganizationDaoTest.java
@@ -19,6 +19,7 @@
*/
package org.sonar.db.organization;
+import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
@@ -26,6 +27,7 @@ import java.util.Map;
import java.util.Optional;
import java.util.Random;
import org.apache.ibatis.exceptions.PersistenceException;
+import org.assertj.core.util.Lists;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -40,6 +42,8 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.db.organization.OrganizationQuery.newOrganizationQueryBuilder;
+import static org.sonar.db.organization.OrganizationQuery.returnAll;
public class OrganizationDaoTest {
private static final long SOME_DATE = 1_200_999L;
@@ -256,19 +260,19 @@ public class OrganizationDaoTest {
@Test
public void selectByQuery_returns_empty_when_table_is_empty() {
- assertThat(underTest.selectByQuery(dbSession, 1, 1)).isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 1, 1)).isEmpty();
}
@Test
public void selectByQuery_returns_single_row_of_table_when_requesting_first_page_of_size_1_or_more() {
insertOrganization(ORGANIZATION_DTO_1);
- assertThat(underTest.selectByQuery(dbSession, 0, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 0, 1))
.hasSize(1)
.extracting("uuid")
.containsOnly(ORGANIZATION_DTO_1.getUuid());
- assertThat(underTest.selectByQuery(dbSession, 0, 10))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 0, 10))
.hasSize(1)
.extracting("uuid")
.containsOnly(ORGANIZATION_DTO_1.getUuid());
@@ -278,9 +282,9 @@ public class OrganizationDaoTest {
public void selectByQuery_returns_empty_on_table_with_single_row_when_not_requesting_the_first_page() {
insertOrganization(ORGANIZATION_DTO_1);
- assertThat(underTest.selectByQuery(dbSession, 1, 1)).isEmpty();
- assertThat(underTest.selectByQuery(dbSession, Math.abs(new Random().nextInt(10)) + 1, 1)).isEmpty();
- assertThat(underTest.selectByQuery(dbSession, 1, 10)).isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 1, 1)).isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), Math.abs(new Random().nextInt(10)) + 1, 1)).isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 1, 10)).isEmpty();
}
@Test
@@ -293,38 +297,149 @@ public class OrganizationDaoTest {
insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid5").setKey("key-5"));
insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid4").setKey("key-4"));
- assertThat(underTest.selectByQuery(dbSession, 0, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 0, 1))
.extracting("uuid", "key")
.containsExactly(tuple("uuid4", "key-4"));
- assertThat(underTest.selectByQuery(dbSession, 1, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 1, 1))
.extracting("uuid", "key")
.containsExactly(tuple("uuid5", "key-5"));
- assertThat(underTest.selectByQuery(dbSession, 2, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 2, 1))
.extracting("uuid", "key")
.containsExactly(tuple("uuid2", "key-2"));
- assertThat(underTest.selectByQuery(dbSession, 3, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 3, 1))
.extracting("uuid", "key")
.containsExactly(tuple("uuid1", "key-1"));
- assertThat(underTest.selectByQuery(dbSession, 4, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 4, 1))
.extracting("uuid", "key")
.containsExactly(tuple("uuid3", "key-3"));
- assertThat(underTest.selectByQuery(dbSession, 5, 1))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 5, 1))
.isEmpty();
- assertThat(underTest.selectByQuery(dbSession, 0, 5))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 0, 5))
.extracting("uuid")
.containsExactly("uuid4", "uuid5", "uuid2", "uuid1", "uuid3");
- assertThat(underTest.selectByQuery(dbSession, 5, 5))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 5, 5))
.isEmpty();
- assertThat(underTest.selectByQuery(dbSession, 0, 3))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 0, 3))
.extracting("uuid")
.containsExactly("uuid4", "uuid5", "uuid2");
- assertThat(underTest.selectByQuery(dbSession, 3, 3))
+ assertThat(underTest.selectByQuery(dbSession, returnAll(), 3, 3))
.extracting("uuid")
.containsExactly("uuid1", "uuid3");
}
@Test
+ public void selectByQuery_with_keys_returns_empty_when_table_is_empty() {
+ assertThat(underTest.selectByQuery(dbSession, newQueryWithKeys("key1", "key2"), 1, 1))
+ .isEmpty();
+ }
+
+ @Test
+ public void selectByQuery_with_keys_returns_single_row_of_table_when_requesting_first_page_of_size_1_or_more() {
+ insertOrganization(ORGANIZATION_DTO_1);
+ insertOrganization(ORGANIZATION_DTO_2);
+
+ OrganizationQuery organizationQuery = newQueryWithKeys(ORGANIZATION_DTO_1.getKey(), ORGANIZATION_DTO_2.getKey());
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 0, 1))
+ .hasSize(1);
+
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 0, 10))
+ .hasSize(2)
+ .extracting(OrganizationDto::getUuid)
+ .containsOnly(ORGANIZATION_DTO_1.getUuid(), ORGANIZATION_DTO_2.getUuid());
+ }
+
+ @Test
+ public void selectByQuery_with_empty_list_of_keys_returns_all() {
+ insertOrganization(ORGANIZATION_DTO_1);
+ insertOrganization(ORGANIZATION_DTO_2);
+
+ OrganizationQuery organizationQuery = newOrganizationQueryBuilder().setKeys(Lists.emptyList()).build();
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 0, 10))
+ .extracting(OrganizationDto::getUuid)
+ .containsOnly(ORGANIZATION_DTO_1.getUuid(), ORGANIZATION_DTO_2.getUuid());
+ }
+
+ @Test
+ public void selectByQuery_with_only_non_existent_keys_returns_empty() {
+ insertOrganization(ORGANIZATION_DTO_1);
+ insertOrganization(ORGANIZATION_DTO_2);
+
+ OrganizationQuery organizationQuery = newQueryWithKeys("foo", "bar", "dog");
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 0, 10))
+ .isEmpty();
+ }
+
+ @Test
+ public void selectByQuery_with_ignores_non_existent_keys() {
+ insertOrganization(ORGANIZATION_DTO_1);
+ insertOrganization(ORGANIZATION_DTO_2);
+
+ OrganizationQuery organizationQuery = newQueryWithKeys(ORGANIZATION_DTO_1.getKey(), "foo", ORGANIZATION_DTO_2.getKey(), "bar", "dog");
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 0, 10))
+ .hasSize(2)
+ .extracting(OrganizationDto::getUuid)
+ .containsOnly(ORGANIZATION_DTO_1.getUuid(), ORGANIZATION_DTO_2.getUuid());
+ }
+
+ @Test
+ public void selectByQuery_with_keys_returns_empty_on_table_with_single_row_when_not_requesting_the_first_page() {
+ insertOrganization(ORGANIZATION_DTO_1);
+ insertOrganization(ORGANIZATION_DTO_2);
+
+ OrganizationQuery organizationQuery = newQueryWithKeys(ORGANIZATION_DTO_1.getKey(), ORGANIZATION_DTO_2.getKey());
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 2, 2)).isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, Math.abs(new Random().nextInt(10)) + 2, 1)).isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, organizationQuery, 2, 10)).isEmpty();
+ }
+
+ @Test
+ public void selectByQuery_with_keys_returns_rows_ordered_by_createdAt_descending_applying_requested_paging() {
+ long time = 1_999_999L;
+ when(system2.now()).thenReturn(time, time + 1_000, time + 2_000, time + 3_000, time + 5_000);
+ insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid3").setKey("key-3"));
+ insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid1").setKey("key-1"));
+ insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid2").setKey("key-2"));
+ insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid5").setKey("key-5"));
+ insertOrganization(copyOf(ORGANIZATION_DTO_1).setUuid("uuid4").setKey("key-4"));
+ OrganizationQuery allExistingKeys = newQueryWithKeys("key-1", "key-2", "key-3", "key-4", "key-5");
+
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 0, 1))
+ .extracting(OrganizationDto::getUuid, OrganizationDto::getKey)
+ .containsExactly(tuple("uuid4", "key-4"));
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 1, 1))
+ .extracting(OrganizationDto::getUuid, OrganizationDto::getKey)
+ .containsExactly(tuple("uuid5", "key-5"));
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 2, 1))
+ .extracting(OrganizationDto::getUuid, OrganizationDto::getKey)
+ .containsExactly(tuple("uuid2", "key-2"));
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 3, 1))
+ .extracting(OrganizationDto::getUuid, OrganizationDto::getKey)
+ .containsExactly(tuple("uuid1", "key-1"));
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 4, 1))
+ .extracting(OrganizationDto::getUuid, OrganizationDto::getKey)
+ .containsExactly(tuple("uuid3", "key-3"));
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 5, 1))
+ .isEmpty();
+
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 0, 5))
+ .extracting(OrganizationDto::getUuid)
+ .containsExactly("uuid4", "uuid5", "uuid2", "uuid1", "uuid3");
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 5, 5))
+ .isEmpty();
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 0, 3))
+ .extracting(OrganizationDto::getUuid)
+ .containsExactly("uuid4", "uuid5", "uuid2");
+ assertThat(underTest.selectByQuery(dbSession, allExistingKeys, 3, 3))
+ .extracting(OrganizationDto::getUuid)
+ .containsExactly("uuid1", "uuid3");
+ }
+
+ private static OrganizationQuery newQueryWithKeys(String... keys) {
+ return newOrganizationQueryBuilder().setKeys(Arrays.asList(keys)).build();
+ }
+
+ @Test
public void update_fails_with_NPE_if_OrganizationDto_is_null() {
expectDtoCanNotBeNull();