aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien Lancelot <julien.lancelot@gmail.com>2013-05-22 15:13:36 +0200
committerJulien Lancelot <julien.lancelot@gmail.com>2013-05-22 15:13:45 +0200
commit3342b4980ff6e0f5a4d96ec00e311b2141c1eff3 (patch)
tree75444a525f107817cb0aa8e05b3f9e73eaa09522
parent7dc0d68a5a3cab41afd5dc1c814a6ed4d4900666 (diff)
downloadsonarqube-3342b4980ff6e0f5a4d96ec00e311b2141c1eff3.tar.gz
sonarqube-3342b4980ff6e0f5a4d96ec00e311b2141c1eff3.zip
SONAR-4301 Replace sql sort on issues by Java sort
-rw-r--r--sonar-application/pom.xml2
-rw-r--r--sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java12
-rw-r--r--sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml32
-rw-r--r--sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java113
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java35
-rw-r--r--sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java181
-rw-r--r--sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java19
-rw-r--r--sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java158
8 files changed, 420 insertions, 132 deletions
diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml
index ec958e9b814..388bc4bb9cd 100644
--- a/sonar-application/pom.xml
+++ b/sonar-application/pom.xml
@@ -206,7 +206,7 @@
<configuration>
<rules>
<requireFilesSize>
- <maxsize>58100000</maxsize>
+ <maxsize>59000000</maxsize>
<minsize>54000000</minsize>
<files>
<file>${project.build.directory}/sonar-${project.version}.zip</file>
diff --git a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
index 5ffa8a84495..ed15bef6208 100644
--- a/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
+++ b/sonar-core/src/main/java/org/sonar/core/issue/db/IssueDao.java
@@ -45,8 +45,6 @@ import static com.google.common.collect.Maps.newHashMap;
*/
public class IssueDao implements BatchComponent, ServerComponent {
- private final static Integer MAX_RESULT = 10000;
-
private final MyBatis mybatis;
public IssueDao(MyBatis mybatis) {
@@ -113,7 +111,7 @@ public class IssueDao implements BatchComponent, ServerComponent {
}
/**
- * The returned IssueDto list contains only the issue id and the project id
+ * The returned IssueDto list contains only the issue id, the project id and the sort column
*/
public List<IssueDto> selectIssueAndProjectIds(final IssueQuery query, final Collection<Integer> authorizedRootProjectIds, SqlSession session) {
return selectIssueAndProjectIds(query, authorizedRootProjectIds, query.maxResults(), session);
@@ -138,24 +136,22 @@ public class IssueDao implements BatchComponent, ServerComponent {
}
@VisibleForTesting
- Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, Boolean asc) {
+ Collection<IssueDto> selectByIds(Collection<Long> ids) {
SqlSession session = mybatis.openSession();
try {
- return selectByIds(ids, sort, asc, session);
+ return selectByIds(ids, session);
} finally {
MyBatis.closeQuietly(session);
}
}
- public Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, Boolean asc, SqlSession session) {
+ public Collection<IssueDto> selectByIds(Collection<Long> ids, SqlSession session) {
if (ids.isEmpty()) {
return Collections.emptyList();
}
Object idsPartition = Lists.partition(newArrayList(ids), 1000);
Map<String, Object> params = newHashMap();
params.put("ids", idsPartition);
- params.put("sort", sort);
- params.put("asc", asc);
return session.selectList("org.sonar.core.issue.db.IssueMapper.selectByIds", params);
}
}
diff --git a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
index f82d0f9e7cf..52ae50afaa3 100644
--- a/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
+++ b/sonar-core/src/main/resources/org/sonar/core/issue/db/IssueMapper.xml
@@ -34,37 +34,28 @@
root.kee as projectKey
</sql>
- <sql id="sortFilter">
- <if test="sort != null">
- order by
+ <sql id="sortColumn">
+ <if test="sort != null">,
<choose>
<when test="'SEVERITY'.equals(sort.name())">
- i.severity
+ i.severity as severity
</when>
<when test="'STATUS'.equals(sort.name())">
- i.status
+ i.status as status
</when>
<when test="'ASSIGNEE'.equals(sort.name())">
- i.assignee
+ i.assignee as assignee
</when>
<when test="'CREATION_DATE'.equals(sort.name())">
- i.issue_creation_date
+ i.issue_creation_date as issueCreationDate
</when>
<when test="'UPDATE_DATE'.equals(sort.name())">
- i.issue_update_date
+ i.issue_update_date as issueUpdateDate
</when>
<when test="'CLOSE_DATE'.equals(sort.name())">
- i.issue_close_date
+ i.issue_close_date as issueCloseDate
</when>
</choose>
- <choose>
- <when test="true.equals(asc)">
- asc
- </when>
- <otherwise>
- desc
- </otherwise>
- </choose>
</if>
</sql>
@@ -153,7 +144,6 @@
and p.id=i.resource_id
and i.project_id=root.id
</where>
- <include refid="sortFilter"/>
</select>
<select id="selectIssueAndComponentIds" parameterType="map" resultType="Issue">
@@ -163,6 +153,7 @@
<select id="selectIssueAndProjectIds" parameterType="map" resultType="Issue">
select i.id, i.project_id as projectId
+ <include refid="sortColumn"/>
<include refid="selectQueryConditions"/>
</select>
@@ -286,10 +277,7 @@
and i.issue_creation_date &lt; #{createdBefore}
</if>
</where>
- <if test="sort == null">
- order by i.id
- </if>
- <include refid="sortFilter"/>
+ order by i.id
</sql>
</mapper>
diff --git a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
index 8418243ce77..73b04ef1796 100644
--- a/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
+++ b/sonar-core/src/test/java/org/sonar/core/issue/db/IssueDaoTest.java
@@ -225,78 +225,6 @@ public class IssueDaoTest extends AbstractDaoTestCase {
}
@Test
- public void should_select_sort_by_severity() {
- setupData("shared", "should_select_returned_sorted_result_by_severity");
-
- IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).asc(true).build();
- List<IssueDto> results = newArrayList(dao.select(query));
- assertThat(results).hasSize(3);
- assertThat(results.get(0).getSeverity()).isEqualTo("BLOCKER");
- assertThat(results.get(1).getSeverity()).isEqualTo("MAJOR");
- assertThat(results.get(2).getSeverity()).isEqualTo("MINOR");
- }
-
- @Test
- public void should_select_sort_by_status() {
- setupData("shared", "should_select_returned_sorted_result_by_status");
-
- IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).asc(true).build();
- List<IssueDto> results = newArrayList(dao.select(query));
- assertThat(results).hasSize(3);
- assertThat(results.get(0).getStatus()).isEqualTo("CLOSED");
- assertThat(results.get(1).getStatus()).isEqualTo("OPEN");
- assertThat(results.get(2).getStatus()).isEqualTo("REOPEN");
- }
-
- @Test
- public void should_select_sort_by_assignee() {
- setupData("shared", "should_select_returned_sorted_result_by_assignee");
-
- IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).asc(true).build();
- List<IssueDto> results = newArrayList(dao.select(query));
- assertThat(results).hasSize(3);
- assertThat(results.get(0).getAssignee()).isEqualTo("arthur");
- assertThat(results.get(1).getAssignee()).isEqualTo("henry");
- assertThat(results.get(2).getAssignee()).isEqualTo("perceval");
- }
-
- @Test
- public void should_select_sort_by_creation_date() {
- setupData("shared", "should_select_returned_sorted_result_by_creation_date");
-
- IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).asc(false).build();
- List<IssueDto> results = newArrayList(dao.select(query));
- assertThat(results).hasSize(3);
- assertThat(results.get(0).getId()).isEqualTo(102);
- assertThat(results.get(1).getId()).isEqualTo(100);
- assertThat(results.get(2).getId()).isEqualTo(101);
- }
-
- @Test
- public void should_select_sort_by_update_date() {
- setupData("shared", "should_select_returned_sorted_result_by_update_date");
-
- IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).asc(false).build();
- List<IssueDto> results = newArrayList(dao.select(query));
- assertThat(results).hasSize(3);
- assertThat(results.get(0).getId()).isEqualTo(102);
- assertThat(results.get(1).getId()).isEqualTo(100);
- assertThat(results.get(2).getId()).isEqualTo(101);
- }
-
- @Test
- public void should_select_sort_by_close_date() {
- setupData("shared", "should_select_returned_sorted_result_by_close_date");
-
- IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).asc(false).build();
- List<IssueDto> results = newArrayList(dao.select(query));
- assertThat(results).hasSize(3);
- assertThat(results.get(0).getId()).isEqualTo(102);
- assertThat(results.get(1).getId()).isEqualTo(100);
- assertThat(results.get(2).getId()).isEqualTo(101);
- }
-
- @Test
public void should_select_issue_and_component_ids() {
setupData("shared", "should_select_issue_and_component_ids");
@@ -313,6 +241,10 @@ public class IssueDaoTest extends AbstractDaoTestCase {
List<IssueDto> results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
assertThat(results).hasSize(3);
+ IssueDto issueDto = results.get(0);
+ assertThat(issueDto.getId()).isNotNull();
+ assertThat(issueDto.getProjectId()).isNotNull();
+
results = dao.selectIssueAndProjectIds(query, newArrayList(399), 2);
assertThat(results).hasSize(2);
@@ -321,6 +253,35 @@ public class IssueDaoTest extends AbstractDaoTestCase {
}
@Test
+ public void should_select_issue_and_project_ids_with_sort_column() {
+ setupData("shared", "should_select_issue_and_project_ids");
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).build();
+ List<IssueDto> results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
+ assertThat(results.get(0).getAssignee()).isNotNull();
+
+ query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).build();
+ results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
+ assertThat(results.get(0).getSeverity()).isNotNull();
+
+ query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).build();
+ results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
+ assertThat(results.get(0).getStatus()).isNotNull();
+
+ query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).build();
+ results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
+ assertThat(results.get(0).getIssueCreationDate()).isNotNull();
+
+ query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).build();
+ results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
+ assertThat(results.get(0).getIssueUpdateDate()).isNotNull();
+
+ query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).build();
+ results = dao.selectIssueAndProjectIds(query, newArrayList(399), 1000);
+ assertThat(results.get(0).getIssueCloseDate()).isNotNull();
+ }
+
+ @Test
public void should_select_open_issues() {
setupData("shared", "should_select_open_issues");
@@ -337,10 +298,10 @@ public class IssueDaoTest extends AbstractDaoTestCase {
public void should_select_by_ids() {
setupData("shared", "should_select_by_ids");
- List<IssueDto> results = newArrayList(dao.selectByIds(newArrayList(100l, 101l, 102l), IssueQuery.Sort.CREATION_DATE, false));
+ List<IssueDto> results = newArrayList(dao.selectByIds(newArrayList(100l, 101l, 102l)));
assertThat(results).hasSize(3);
- assertThat(results.get(0).getId()).isEqualTo(102);
- assertThat(results.get(1).getId()).isEqualTo(100);
- assertThat(results.get(2).getId()).isEqualTo(101);
+ assertThat(results.get(0).getId()).isEqualTo(100);
+ assertThat(results.get(1).getId()).isEqualTo(101);
+ assertThat(results.get(2).getId()).isEqualTo(102);
}
}
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java b/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java
index caea62016a2..1ce627cc59f 100644
--- a/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java
+++ b/sonar-server/src/main/java/org/sonar/server/issue/DefaultIssueFinder.java
@@ -106,12 +106,17 @@ public class DefaultIssueFinder implements IssueFinder {
// 2. Select the authorized ids of all the issues that match the query
List<IssueDto> authorizedIssues = issueDao.selectIssueAndProjectIds(query, rootProjectIds, sqlSession);
- // 3. Apply pagination
- Paging paging = Paging.create(query.pageSize(), query.pageIndex(), authorizedIssues.size());
- Set<Long> pagedIssueIds = pagedIssueIds(authorizedIssues, paging);
+ // 3. Sort all authorized issues
+ Collection<IssueDto> authorizedSortedIssues = new IssuesFinderSort(authorizedIssues, query).sort();
+
+ // 4. Apply pagination
+ Paging paging = Paging.create(query.pageSize(), query.pageIndex(), authorizedSortedIssues.size());
+ Set<Long> pagedIssueIds = pagedIssueIds(authorizedSortedIssues, paging);
+
+ // 5. Load issues and their related data (rules, components, projects, comments, action plans, ...) and sort then again
+ Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, sqlSession);
+ Collection<IssueDto> pagedSortedIssues = new IssuesFinderSort(pagedIssues, query).sort();
- // 4. Load issues and their related data (rules, components, comments, action plans, ...)
- Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, query.sort(), query.asc(), sqlSession);
Map<String, DefaultIssue> issuesByKey = newHashMap();
List<Issue> issues = newArrayList();
Set<Integer> ruleIds = Sets.newHashSet();
@@ -119,7 +124,7 @@ public class DefaultIssueFinder implements IssueFinder {
Set<Integer> projectIds = Sets.newHashSet();
Set<String> actionPlanKeys = Sets.newHashSet();
Set<String> users = Sets.newHashSet();
- for (IssueDto dto : pagedIssues) {
+ for (IssueDto dto : pagedSortedIssues) {
DefaultIssue defaultIssue = dto.toDefaultIssue();
issuesByKey.put(dto.getKee(), defaultIssue);
issues.add(defaultIssue);
@@ -144,15 +149,15 @@ public class DefaultIssueFinder implements IssueFinder {
}
return new DefaultResults(issues,
- findRules(ruleIds),
- findComponents(componentIds),
- findProjects(projectIds),
- findActionPlans(actionPlanKeys),
- findUsers(users),
- paging,
- false,
- authorizedIssues.size() != query.maxResults()
- // TODO
+ findRules(ruleIds),
+ findComponents(componentIds),
+ findProjects(projectIds),
+ findActionPlans(actionPlanKeys),
+ findUsers(users),
+ paging,
+ false,
+ authorizedIssues.size() != query.maxResults()
+ // TODO
// authorizedIssues.size() != allIssues.size()
);
} finally {
diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java b/sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java
new file mode 100644
index 00000000000..086365f974d
--- /dev/null
+++ b/sonar-server/src/main/java/org/sonar/server/issue/IssuesFinderSort.java
@@ -0,0 +1,181 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.server.issue;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Ordering;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.rule.Severity;
+import org.sonar.core.issue.db.IssueDto;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+
+class IssuesFinderSort {
+
+ private Collection<IssueDto> issues;
+ private IssueQuery query;
+
+ public IssuesFinderSort(Collection<IssueDto> issues, IssueQuery query) {
+ this.issues = issues;
+ this.query = query;
+ }
+
+ public Collection<IssueDto> sort() {
+ if (query.sort() != null) {
+ IssueProcessor issueProcessor;
+ switch (query.sort()) {
+ case ASSIGNEE:
+ issueProcessor = new AssigneeSortIssueProcessor();
+ break;
+ case SEVERITY:
+ issueProcessor = new SeveritySortIssueProcessor();
+ break;
+ case STATUS:
+ issueProcessor = new StatusSortIssueProcessor();
+ break;
+ case CREATION_DATE:
+ issueProcessor = new CreationDateSortIssueProcessor();
+ break;
+ case UPDATE_DATE:
+ issueProcessor = new UpdateDateSortIssueProcessor();
+ break;
+ case CLOSE_DATE:
+ issueProcessor = new CloseDateSortIssueProcessor();
+ break;
+ default:
+ throw new IllegalArgumentException("Cannot sort issues on field : " + query.sort().name());
+ }
+ return issueProcessor.sort(issues, query.asc());
+ }
+ return issues;
+ }
+
+ abstract static class IssueProcessor {
+ abstract Function sortFieldFunction();
+
+ abstract Ordering sortFieldOrdering(boolean ascending);
+
+ final List<IssueDto> sort(Collection<IssueDto> issueDtos, boolean ascending) {
+ Ordering<IssueDto> ordering = sortFieldOrdering(ascending).onResultOf(sortFieldFunction());
+ return ordering.immutableSortedCopy(issueDtos);
+ }
+ }
+
+ abstract static class TextSortIssueProcessor extends IssueProcessor {
+ @Override
+ Function sortFieldFunction() {
+ return new Function<IssueDto, String>() {
+ public String apply(IssueDto issueDto) {
+ return sortField(issueDto);
+ }
+ };
+ }
+
+ abstract String sortField(IssueDto issueDto);
+
+ @Override
+ Ordering sortFieldOrdering(boolean ascending) {
+ Ordering<String> ordering = Ordering.from(String.CASE_INSENSITIVE_ORDER).nullsLast();
+ if (!ascending) {
+ ordering = ordering.reverse();
+ }
+ return ordering;
+ }
+ }
+
+ static class AssigneeSortIssueProcessor extends TextSortIssueProcessor {
+ @Override
+ String sortField(IssueDto issueDto) {
+ return issueDto.getAssignee();
+ }
+ }
+
+ static class StatusSortIssueProcessor extends TextSortIssueProcessor {
+ @Override
+ String sortField(IssueDto issueDto) {
+ return issueDto.getStatus();
+ }
+ }
+
+ static class SeveritySortIssueProcessor extends IssueProcessor {
+ @Override
+ Function sortFieldFunction() {
+ return new Function<IssueDto, Integer>() {
+ public Integer apply(IssueDto issueDto) {
+ return Severity.ALL.indexOf(issueDto.getSeverity());
+ }
+ };
+ }
+
+ @Override
+ Ordering sortFieldOrdering(boolean ascending) {
+ Ordering<Integer> ordering = Ordering.<Integer>natural().nullsLast();
+ if (!ascending) {
+ ordering = ordering.reverse();
+ }
+ return ordering;
+ }
+ }
+
+ abstract static class DateSortRowProcessor extends IssueProcessor {
+ @Override
+ Function sortFieldFunction() {
+ return new Function<IssueDto, Date>() {
+ public Date apply(IssueDto issueDto) {
+ return sortField(issueDto);
+ }
+ };
+ }
+
+ abstract Date sortField(IssueDto issueDto);
+
+ @Override
+ Ordering sortFieldOrdering(boolean ascending) {
+ Ordering<Date> ordering = Ordering.<Date>natural().nullsLast();
+ if (!ascending) {
+ ordering = ordering.reverse();
+ }
+ return ordering;
+ }
+ }
+
+ static class CreationDateSortIssueProcessor extends DateSortRowProcessor {
+ @Override
+ Date sortField(IssueDto issueDto) {
+ return issueDto.getIssueCreationDate();
+ }
+ }
+
+ static class UpdateDateSortIssueProcessor extends DateSortRowProcessor {
+ @Override
+ Date sortField(IssueDto issueDto) {
+ return issueDto.getIssueUpdateDate();
+ }
+ }
+
+ static class CloseDateSortIssueProcessor extends DateSortRowProcessor {
+ @Override
+ Date sortField(IssueDto issueDto) {
+ return issueDto.getIssueCloseDate();
+ }
+ }
+}
diff --git a/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java b/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java
index b2dc2fcfe90..fbb71cc901b 100644
--- a/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/issue/DefaultIssueFinderTest.java
@@ -50,7 +50,6 @@ import static org.mockito.Matchers.anyCollection;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.*;
public class DefaultIssueFinderTest {
@@ -82,7 +81,7 @@ public class DefaultIssueFinderTest {
.setRuleKey_unit_test_only("squid", "AvoidCycle")
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
verify(issueDao).selectIssueAndProjectIds(eq(query), eq(newHashSet(100)), any(SqlSession.class));
@@ -106,7 +105,7 @@ public class DefaultIssueFinderTest {
.setProjectKey_unit_test_only("struts")
.setRuleKey_unit_test_only("squid", "AvoidCycle")
.setStatus("OPEN").setResolution("OPEN");
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(newArrayList(issue1));
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(newArrayList(issue1));
finder.find(query);
verify(issueDao).selectIssueAndProjectIds(eq(query), eq(Collections.<Integer>emptySet()), any(SqlSession.class));
@@ -134,7 +133,7 @@ public class DefaultIssueFinderTest {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndProjectIds(eq(query), eq(newHashSet(100)), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.paging().offset()).isEqualTo(0);
@@ -142,7 +141,7 @@ public class DefaultIssueFinderTest {
assertThat(results.paging().pages()).isEqualTo(2);
// Only one result is expected because the limit is 1
- verify(issueDao).selectByIds(eq(newHashSet(1L)), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class));
+ verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class));
}
@Test
@@ -178,7 +177,7 @@ public class DefaultIssueFinderTest {
.setRuleKey_unit_test_only("squid", "AvoidCycle")
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
@@ -206,7 +205,7 @@ public class DefaultIssueFinderTest {
.setRuleKey_unit_test_only("squid", "AvoidCycle")
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
@@ -233,7 +232,7 @@ public class DefaultIssueFinderTest {
.setRuleKey_unit_test_only("squid", "AvoidCycle")
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
@@ -260,7 +259,7 @@ public class DefaultIssueFinderTest {
.setRuleKey_unit_test_only("squid", "AvoidCycle")
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
when(actionPlanService.findByKeys(anyCollection())).thenReturn(newArrayList(actionPlan1, actionPlan2));
IssueQueryResult results = finder.find(query);
@@ -275,7 +274,7 @@ public class DefaultIssueFinderTest {
grantAccessRights();
IssueQuery query = IssueQuery.builder().build();
when(issueDao.selectIssueAndProjectIds(eq(query), anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
- when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
+ when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).isEmpty();
diff --git a/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java b/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java
new file mode 100644
index 00000000000..d7a458965fd
--- /dev/null
+++ b/sonar-server/src/test/java/org/sonar/server/issue/IssuesFinderSortTest.java
@@ -0,0 +1,158 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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.server.issue;
+
+import org.apache.commons.lang.time.DateUtils;
+import org.junit.Test;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.core.issue.db.IssueDto;
+
+import java.util.Date;
+import java.util.List;
+
+import static com.google.common.collect.Lists.newArrayList;
+import static org.fest.assertions.Assertions.assertThat;
+
+public class IssuesFinderSortTest {
+
+ @Test
+ public void should_sort_by_assignee() {
+ IssueDto issue1 = new IssueDto().setId(1L).setAssignee("perceval");
+ IssueDto issue2 = new IssueDto().setId(2L).setAssignee("arthur");
+ IssueDto issue3 = new IssueDto().setId(3L).setAssignee("vincent");
+ IssueDto issue4 = new IssueDto().setId(4L).setAssignee(null);
+ List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3, issue4);
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.ASSIGNEE).asc(true).build();
+ IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query);
+
+ List<IssueDto> result = newArrayList(issuesFinderSort.sort());
+
+ assertThat(result).hasSize(4);
+ assertThat(result.get(0).getAssignee()).isEqualTo("arthur");
+ assertThat(result.get(1).getAssignee()).isEqualTo("perceval");
+ assertThat(result.get(2).getAssignee()).isEqualTo("vincent");
+ assertThat(result.get(3).getAssignee()).isNull();
+ }
+
+ @Test
+ public void should_sort_by_status() {
+ IssueDto issue1 = new IssueDto().setId(1L).setStatus("CLOSED");
+ IssueDto issue2 = new IssueDto().setId(2L).setStatus("REOPENED");
+ IssueDto issue3 = new IssueDto().setId(3L).setStatus("OPEN");
+ List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3);
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.STATUS).asc(false).build();
+ IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query);
+
+ List<IssueDto> result = newArrayList(issuesFinderSort.sort());
+
+ assertThat(result).hasSize(3);
+ assertThat(result.get(0).getStatus()).isEqualTo("REOPENED");
+ assertThat(result.get(1).getStatus()).isEqualTo("OPEN");
+ assertThat(result.get(2).getStatus()).isEqualTo("CLOSED");
+ }
+
+ @Test
+ public void should_sort_by_severity() {
+ IssueDto issue1 = new IssueDto().setId(1L).setSeverity("INFO");
+ IssueDto issue2 = new IssueDto().setId(2L).setSeverity("BLOCKER");
+ IssueDto issue3 = new IssueDto().setId(3L).setSeverity("MAJOR");
+ List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3);
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.SEVERITY).asc(true).build();
+ IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query);
+
+ List<IssueDto> result = newArrayList(issuesFinderSort.sort());
+
+ assertThat(result).hasSize(3);
+ assertThat(result.get(0).getSeverity()).isEqualTo("INFO");
+ assertThat(result.get(1).getSeverity()).isEqualTo("MAJOR");
+ assertThat(result.get(2).getSeverity()).isEqualTo("BLOCKER");
+ }
+
+ @Test
+ public void should_sort_by_creation_date() {
+ Date date = new Date();
+ Date date1 = DateUtils.addDays(date, -3);
+ Date date2 = DateUtils.addDays(date, -2);
+ Date date3 = DateUtils.addDays(date, -1);
+ IssueDto issue1 = new IssueDto().setId(1L).setIssueCreationDate(date1);
+ IssueDto issue2 = new IssueDto().setId(2L).setIssueCreationDate(date3);
+ IssueDto issue3 = new IssueDto().setId(3L).setIssueCreationDate(date2);
+ List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3);
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CREATION_DATE).asc(false).build();
+ IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query);
+
+ List<IssueDto> result = newArrayList(issuesFinderSort.sort());
+
+ assertThat(result).hasSize(3);
+ assertThat(result.get(0).getIssueCreationDate()).isEqualTo(date3);
+ assertThat(result.get(1).getIssueCreationDate()).isEqualTo(date2);
+ assertThat(result.get(2).getIssueCreationDate()).isEqualTo(date1);
+ }
+
+ @Test
+ public void should_sort_by_update_date() {
+ Date date = new Date();
+ Date date1 = DateUtils.addDays(date, -3);
+ Date date2 = DateUtils.addDays(date, -2);
+ Date date3 = DateUtils.addDays(date, -1);
+ IssueDto issue1 = new IssueDto().setId(1L).setIssueUpdateDate(date1);
+ IssueDto issue2 = new IssueDto().setId(2L).setIssueUpdateDate(date3);
+ IssueDto issue3 = new IssueDto().setId(3L).setIssueUpdateDate(date2);
+ List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3);
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.UPDATE_DATE).asc(false).build();
+ IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query);
+
+ List<IssueDto> result = newArrayList(issuesFinderSort.sort());
+
+ assertThat(result).hasSize(3);
+ assertThat(result.get(0).getIssueUpdateDate()).isEqualTo(date3);
+ assertThat(result.get(1).getIssueUpdateDate()).isEqualTo(date2);
+ assertThat(result.get(2).getIssueUpdateDate()).isEqualTo(date1);
+ }
+
+ @Test
+ public void should_sort_by_close_date() {
+ Date date = new Date();
+ Date date1 = DateUtils.addDays(date, -3);
+ Date date2 = DateUtils.addDays(date, -2);
+ Date date3 = DateUtils.addDays(date, -1);
+ IssueDto issue1 = new IssueDto().setId(1L).setIssueCloseDate(date1);
+ IssueDto issue2 = new IssueDto().setId(2L).setIssueCloseDate(date3);
+ IssueDto issue3 = new IssueDto().setId(3L).setIssueCloseDate(date2);
+ List<IssueDto> dtoList = newArrayList(issue1, issue2, issue3);
+
+ IssueQuery query = IssueQuery.builder().sort(IssueQuery.Sort.CLOSE_DATE).asc(false).build();
+ IssuesFinderSort issuesFinderSort = new IssuesFinderSort(dtoList, query);
+
+ List<IssueDto> result = newArrayList(issuesFinderSort.sort());
+
+ assertThat(result).hasSize(3);
+ assertThat(result.get(0).getIssueCloseDate()).isEqualTo(date3);
+ assertThat(result.get(1).getIssueCloseDate()).isEqualTo(date2);
+ assertThat(result.get(2).getIssueCloseDate()).isEqualTo(date1);
+ }
+
+}