import org.sonar.core.persistence.MyBatis;
import javax.annotation.CheckForNull;
+
import java.util.Collection;
import java.util.Collections;
import java.util.List;
return mapper.selectIssueAndComponentIds(query);
}
- Collection<IssueDto> selectByIds(Collection<Long> ids) {
+ @VisibleForTesting
+ Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, boolean asc) {
SqlSession session = mybatis.openSession();
try {
- return selectByIds(ids, session);
+ return selectByIds(ids, sort, asc, session);
} finally {
MyBatis.closeQuietly(session);
}
}
- public Collection<IssueDto> selectByIds(Collection<Long> ids, SqlSession session) {
+ public Collection<IssueDto> selectByIds(Collection<Long> ids, IssueQuery.Sort sort, boolean asc, SqlSession session) {
if (ids.isEmpty()) {
return Collections.emptyList();
}
- List<List<Long>> idsPartition = Lists.partition(newArrayList(ids), 1000);
- Map<String, List<List<Long>>> params = ImmutableMap.of("ids", idsPartition);
+ Object idsPartition = Lists.partition(newArrayList(ids), 1000);
+ Map<String, Object> params = ImmutableMap.of("ids", idsPartition, "sort", sort, "asc", asc);
return session.selectList("org.sonar.core.issue.db.IssueMapper.selectByIds", params);
}
}
p.kee as componentKey
</sql>
+ <sql id="sortFilter">
+ <if test="sort != null">
+ order by
+ <choose>
+ <when test="'SEVERITY'.equals(sort.name())">
+ i.severity
+ </when>
+ <when test="'STATUS'.equals(sort.name())">
+ i.status
+ </when>
+ <when test="'ASSIGNEE'.equals(sort.name())">
+ i.assignee
+ </when>
+ <when test="'CREATION_DATE'.equals(sort.name())">
+ i.issue_creation_date
+ </when>
+ <when test="'UPDATE_DATE'.equals(sort.name())">
+ i.issue_update_date
+ </when>
+ <when test="'CLOSE_DATE'.equals(sort.name())">
+ i.issue_close_date
+ </when>
+ </choose>
+ <choose>
+ <when test="true.equals(asc)">
+ asc
+ </when>
+ <otherwise>
+ desc
+ </otherwise>
+ </choose>
+ </if>
+ </sql>
+
<insert id="insert" parameterType="Issue" useGeneratedKeys="false" keyProperty="id">
INSERT INTO issues (kee, resource_id, rule_id, action_plan_key, severity, manual_severity,
message, line, effort_to_fix, status,
and i.rule_id=r.id
and p.id=i.resource_id
</where>
+ <include refid="sortFilter"/>
</select>
<select id="selectIssueAndComponentIds" parameterType="map" resultType="Issue">
<if test="sort == null">
order by i.id
</if>
- <if test="sort != null">
- order by
- <choose>
- <when test="'CREATION_DATE'.equals(sort.name())">
- i.issue_creation_date
- </when>
- <when test="'UPDATE_DATE'.equals(sort.name())">
- i.issue_update_date
- </when>
- <when test="'CLOSE_DATE'.equals(sort.name())">
- i.issue_close_date
- </when>
- <when test="'ASSIGNEE'.equals(sort.name())">
- i.assignee
- </when>
- </choose>
- <choose>
- <when test="true.equals(asc)">
- asc
- </when>
- <otherwise>
- desc
- </otherwise>
- </choose>
- </if>
+ <include refid="sortFilter"/>
</sql>
</mapper>
import org.sonar.api.utils.DateUtils;
import org.sonar.core.persistence.AbstractDaoTestCase;
-import java.util.Collection;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
assertThat(dao.select(query)).hasSize(3);
}
+ @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");
+ 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.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");
public void should_select_by_ids() {
setupData("shared", "should_select_by_ids");
- Collection<IssueDto> results = dao.selectByIds(newArrayList(100l, 101l, 102l));
+ List<IssueDto> results = newArrayList(dao.selectByIds(newArrayList(100l, 101l, 102l), IssueQuery.Sort.CREATION_DATE, false));
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);
}
}
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
- issue_creation_date="2013-04-16"
- issue_update_date="2013-04-16"
- issue_close_date="2013-04-16"
- created_at="2013-04-16"
- updated_at="2013-04-16"
+ issue_creation_date="2013-04-17"
+ issue_update_date="2013-04-17"
+ issue_close_date="2013-04-17"
+ created_at="2013-04-17"
+ updated_at="2013-04-17"
/>
<issues
assignee="perceval"
author_login="[null]"
attributes="JIRA=FOO-1234"
- issue_creation_date="2013-04-16"
- issue_update_date="2013-04-16"
- issue_close_date="2013-04-16"
- created_at="2013-04-16"
- updated_at="2013-04-16"
+ issue_creation_date="2013-04-18"
+ issue_update_date="2013-04-18"
+ issue_close_date="2013-04-18"
+ created_at="2013-04-18"
+ updated_at="2013-04-18"
/>
</dataset>
+++ /dev/null
-<dataset>
-
- <!-- rule 500 -->
- <issues
- id="100"
- kee="ABCDE-1"
- resource_id="401"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- message="[null]"
- line="200"
- effort_to_fix="4.2"
- status="OPEN"
- resolution="FIXED"
- checksum="XXX"
- reporter="arthur"
- assignee="arthur"
- author_login="[null]"
- attributes="JIRA=FOO-1234"
- issue_creation_date="2013-04-16"
- issue_update_date="2013-04-16"
- issue_close_date="2013-04-16"
- created_at="2013-04-16"
- updated_at="2013-04-16"
- />
-
- <issues
- id="101"
- kee="ABCDE-2"
- resource_id="401"
- rule_id="500"
- severity="BLOCKER"
- manual_severity="[false]"
- message="[null]"
- line="200"
- effort_to_fix="4.2"
- status="OPEN"
- resolution="FIXED"
- checksum="XXX"
- reporter="arthur"
- assignee="perceval"
- author_login="[null]"
- attributes="JIRA=FOO-1234"
- issue_creation_date="2013-04-16"
- issue_update_date="2013-04-16"
- issue_close_date="2013-04-16"
- created_at="2013-04-16"
- updated_at="2013-04-16"
- />
-
-
- <!-- rule 501 -->
- <issues
- id="102"
- kee="ABCDE-3"
- resource_id="401"
- rule_id="501"
- severity="BLOCKER"
- manual_severity="[false]"
- message="[null]"
- line="200"
- effort_to_fix="4.2"
- status="OPEN"
- resolution="FIXED"
- checksum="XXX"
- reporter="arthur"
- assignee="henry"
- author_login="[null]"
- attributes="JIRA=FOO-1234"
- issue_creation_date="2013-04-16"
- issue_update_date="2013-04-16"
- issue_close_date="2013-04-16"
- created_at="2013-04-16"
- updated_at="2013-04-16"
- />
-</dataset>
--- /dev/null
+<dataset>
+
+ <!-- rule 500 -->
+ <issues
+ id="100"
+ kee="ABCDE-1"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="arthur"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="101"
+ kee="ABCDE-2"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+
+ <!-- rule 501 -->
+ <issues
+ id="102"
+ kee="ABCDE-3"
+ resource_id="401"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="henry"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+</dataset>
--- /dev/null
+<dataset>
+
+ <!-- rule 500 -->
+ <issues
+ id="100"
+ kee="ABCDE-1"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="arthur"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-17"
+ issue_close_date="2013-04-17"
+ created_at="2013-04-16"
+ updated_at="2013-04-17"
+ />
+
+ <issues
+ id="101"
+ kee="ABCDE-2"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+
+ <!-- rule 501 -->
+ <issues
+ id="102"
+ kee="ABCDE-3"
+ resource_id="401"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="henry"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-18"
+ issue_close_date="2013-04-18"
+ created_at="2013-04-16"
+ updated_at="2013-04-18"
+ />
+</dataset>
--- /dev/null
+<dataset>
+
+ <issues
+ id="100"
+ kee="ABCDE-1"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="arthur"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-15"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-15"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="101"
+ kee="ABCDE-2"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-14"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-14"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="102"
+ kee="ABCDE-3"
+ resource_id="401"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="henry"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+</dataset>
--- /dev/null
+<dataset>
+
+ <issues
+ id="100"
+ kee="ABCDE-1"
+ resource_id="401"
+ rule_id="500"
+ severity="MINOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="arthur"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="101"
+ kee="ABCDE-2"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="102"
+ kee="ABCDE-3"
+ resource_id="401"
+ rule_id="501"
+ severity="MAJOR"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="henry"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+</dataset>
--- /dev/null
+<dataset>
+
+ <!-- rule 500 -->
+ <issues
+ id="100"
+ kee="ABCDE-1"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="arthur"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="101"
+ kee="ABCDE-2"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="CLOSED"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+
+ <!-- rule 501 -->
+ <issues
+ id="102"
+ kee="ABCDE-3"
+ resource_id="401"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="REOPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="henry"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+</dataset>
--- /dev/null
+<dataset>
+
+ <issues
+ id="100"
+ kee="ABCDE-1"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="arthur"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-17"
+ issue_close_date="2013-04-17"
+ created_at="2013-04-16"
+ updated_at="2013-04-17"
+ />
+
+ <issues
+ id="101"
+ kee="ABCDE-2"
+ resource_id="401"
+ rule_id="500"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="perceval"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-16"
+ issue_close_date="2013-04-16"
+ created_at="2013-04-16"
+ updated_at="2013-04-16"
+ />
+
+ <issues
+ id="102"
+ kee="ABCDE-3"
+ resource_id="401"
+ rule_id="501"
+ severity="BLOCKER"
+ manual_severity="[false]"
+ message="[null]"
+ line="200"
+ effort_to_fix="4.2"
+ status="OPEN"
+ resolution="FIXED"
+ checksum="XXX"
+ reporter="arthur"
+ assignee="henry"
+ author_login="[null]"
+ attributes="JIRA=FOO-1234"
+ issue_creation_date="2013-04-16"
+ issue_update_date="2013-04-18"
+ issue_close_date="2013-04-18"
+ created_at="2013-04-16"
+ updated_at="2013-04-18"
+ />
+</dataset>
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
+
import java.util.Collection;
import java.util.Date;
public static final int MAX_ISSUE_KEYS = 500;
public static enum Sort {
- CREATION_DATE, UPDATE_DATE, CLOSE_DATE, ASSIGNEE, SEVERITY
+ CREATION_DATE, UPDATE_DATE, CLOSE_DATE, ASSIGNEE, SEVERITY, STATUS
}
private final Collection<String> issueKeys;
private final Date createdAfter;
private final Date createdBefore;
private final Sort sort;
- private final boolean asc;
+ private final Boolean asc;
private final String requiredRole;
// max results per page
return sort;
}
- public boolean asc() {
+ public Boolean asc() {
return asc;
}
private Date createdAfter;
private Date createdBefore;
private Sort sort;
- private boolean asc = false;
+ private Boolean asc = false;
private Integer pageSize;
private Integer pageIndex;
private String requiredRole;
return this;
}
- public Builder asc(boolean asc) {
+ public Builder asc(Boolean asc) {
this.asc = asc;
return this;
}
import org.sonar.server.platform.UserSession;
import javax.annotation.CheckForNull;
+
import java.util.Collection;
import java.util.List;
import java.util.Map;
Set<Long> pagedIssueIds = pagedIssueIds(authorizedIssues, paging);
// 4. Load issues and their related data (rules, components, comments, action plans, ...)
- Collection<IssueDto> pagedIssues = issueDao.selectByIds(pagedIssueIds, sqlSession);
+ 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();
import org.sonar.server.util.RubyUtils;
import javax.annotation.Nullable;
+
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
builder.pageIndex(RubyUtils.toInteger(props.get("pageIndex")));
String sort = (String) props.get("sort");
if (sort != null) {
- builder.sort(IssueQuery.Sort.valueOf(sort));
+ builder.sort(IssueQuery.Sort.valueOf(sort.toUpperCase()));
+ builder.asc(RubyUtils.toBoolean(props.get("asc")));
}
return builder.build();
}
@filter.criteria=criteria_params
@filter.execute
- # TODO replace by project from issues result API
@project = Project.by_key(@filter.criteria('componentRoots')).root_project if @filter.criteria('componentRoots')
end
--- /dev/null
+#
+# Sonar, entreprise quality control 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.
+#
+module IssuesHelper
+
+ def column_html(filter, column_label, column_tooltip, sort)
+ filter_sort = filter.criteria[:sort]
+ filter_asc = filter.criteria[:asc] == 'true' ? true : false
+ html = link_to_function(h(column_label), "refreshList('#{escape_javascript sort}',#{!filter_asc}, #{filter.criteria[:page]||1})", :title => h(column_tooltip))
+ if sort == filter_sort
+ html << (filter_asc ? image_tag("asc12.png") : image_tag("desc12.png"))
+ end
+ html
+ end
+
+end
require 'set'
class IssueFilter
- CRITERIA_SEPARATOR = '|'
- CRITERIA_KEY_VALUE_SEPARATOR = ','
-
attr_reader :paging, :issues, :issues_result
def criteria(key=nil)
@issues_result = nil
@paging = nil
@issues = nil
- criteria['pageSize'] = 25
+ criteria['pageSize'] = 100
+ criteria['sort'] ||= 'CREATION_DATE'
+ criteria['asc'] ||= 'false'
self
end
+<% content_for :script do %>
+ <script>
+ var filterCriteria = <%= @filter.criteria.to_json -%>;
+
+ function refreshList(sort, asc, page) {
+ $j('#issue-filter-foot_pages').hide();
+ $j('#issue-filter-foot_loading').show();
+
+ filterCriteria['sort']=sort;
+ filterCriteria['asc']=asc;
+ filterCriteria['pageIndex']=page;
+ var url=baseUrl + '/issues/search?' + $j.param(filterCriteria);
+
+ window.location = url;
+ return false;
+ }
+ </script>
+<% end %>
+
<%
if @filter.issues && !@filter.issues.empty?
colspan = 8
<thead>
<tr>
<th width="1%" nowrap>
- <%= message('severity_abbreviated') -%>
+ <%= column_html(@filter, message('severity_abbreviated'), message('severity'), 'SEVERITY') %>
</th>
<th width="1%" nowrap>
- <%= message('status_abbreviated') -%>
+ <%= column_html(@filter, message('status_abbreviated'), message('status'), 'STATUS') %>
</th>
<th>
<%= message('description') -%>
<%= message('component') -%>
</th>
<th>
- <%= message('issue_filter.header.assignee') -%>
+ <%= column_html(@filter, message('issue_filter.header.assignee'), message('issue_filter.header.assignee'), 'ASSIGNEE') %>
</th>
<th>
<%= message('issue_filter.header.action_plan') -%>
</th>
<th>
- <%= message('issue_filter.header.creation_date') -%>
+ <%= column_html(@filter, message('issue_filter.header.creation_date'), message('issue_filter.header.creation_date'), 'CREATION_DATE') %>
</th>
<th>
- <%= message('issue_filter.header.update_date') -%>
+ <%= column_html(@filter, message('issue_filter.header.update_date'), message('issue_filter.header.update_date'), 'UPDATE_DATE') %>
</th>
</tr>
</thead>
<img src="<%= ApplicationController.root_context -%>/images/status/<%= issue.status -%>.png" title="<%= message(issue.status.downcase).capitalize -%>"/>
</td>
<td>
- <%= link_to h(issue.message), :controller => 'issue', :action => 'view', :id => issue.key -%>
+ <%= link_to h(truncate(issue.message, :length => 100)), :controller => 'issue', :action => 'view', :id => issue.key -%>
</td>
<td>
<%= h @filter.issues_result.component(issue).name -%>
<% end %>
</tbody>
- <%= paginate_java(@filter.paging, :colspan => colspan, :include_loading_icon => true) { |label, page_id|
+ <%= paginate_java(@filter.paging, :colspan => colspan, :id => 'issue-filter-foot', :include_loading_icon => true) { |label, page_id|
link_to(label, @filter.criteria.merge({:pageIndex => page_id}))
} -%>
<ul class="sidebar gray-sidebar">
<form method="GET" action="<%= ApplicationController.root_context -%>/issues/search" >
+
+ <input type="hidden" name="sort" value="<%= @filter.criteria('sort')-%>"/>
+ <input type="hidden" name="asc" value="<%= @filter.criteria('asc') -%>"/>
+
<li class="sidebar-title">
<%= message('issue_filter.new_search') -%>
</li>
<li id="criteria-project" class="marginbottom5">
- <!-- TODO replace by project from issues result API-->
<% selected_project = @project if @filter.criteria('componentRoots') %>
<%= message 'issue_filter.criteria.project' -%>:
<%= resource_select_tag 'componentRoots', :resource_type_property => 'supportsGlobalDashboards', :width => '100%',
<%= render :partial => 'issues/sidebar' -%>
</div>
+
<div class="page-split-right">
<div id="content">
<div class="marginbottom10">
+ <% if @filter.issues_result && @filter.issues_result.securityExclusions() %>
+ <p class="notes"><%= message('results_not_display_due_to_security') -%></p>
+ <% end %>
+
<%= render :partial => 'list' -%>
</div>
</div>
import static org.mockito.Matchers.anySet;
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 {
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
when(authorizationDao.keepAuthorizedComponentIds(anySet(), anyInt(), anyString(), any(SqlSession.class))).thenReturn(newHashSet(123));
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(newArrayList(issue1));
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(newArrayList(issue1));
IssueQueryResult results = finder.find(query);
- verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class));
+ verify(issueDao).selectByIds(eq(newHashSet(1L)), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class));
assertThat(results.securityExclusions()).isTrue();
}
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.paging().offset()).isEqualTo(0);
assertThat(results.paging().pages()).isEqualTo(2);
// Only one result is expected because the limit is 1
- verify(issueDao).selectByIds(eq(newHashSet(1L)), any(SqlSession.class));
+ verify(issueDao).selectByIds(eq(newHashSet(1L)), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class));
}
@Test
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
IssueQueryResult results = finder.find(query);
assertThat(results.issues()).hasSize(2);
.setStatus("OPEN").setResolution("OPEN");
List<IssueDto> dtoList = newArrayList(issue1, issue2);
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(dtoList);
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(dtoList);
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(dtoList);
when(actionPlanService.findByKeys(anyCollection())).thenReturn(newArrayList(actionPlan1, actionPlan2));
IssueQueryResult results = finder.find(query);
grantAccessRights();
IssueQuery query = IssueQuery.builder().build();
when(issueDao.selectIssueAndComponentIds(eq(query), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
- when(issueDao.selectByIds(anyCollection(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
+ when(issueDao.selectByIds(anyCollection(), any(IssueQuery.Sort.class), anyBoolean(), any(SqlSession.class))).thenReturn(Collections.<IssueDto>emptyList());
IssueQueryResult results = finder.find(query);
map.put("rules", "squid:AvoidCycle,findbugs:NullReference");
map.put("pageSize", 10l);
map.put("pageIndex", 50);
+ map.put("sort", "creation_date");
+ map.put("asc", true);
IssueQuery query = new PublicRubyIssueService(finder).toQuery(map);
assertThat(query.issueKeys()).containsOnly("ABCDE1234");
assertThat(query.createdBefore()).isEqualTo(DateUtils.parseDateTime("2013-04-17T09:08:24+0200"));
assertThat(query.pageSize()).isEqualTo(10);
assertThat(query.pageIndex()).isEqualTo(50);
+ assertThat(query.sort()).isEqualTo(IssueQuery.Sort.CREATION_DATE);
+ assertThat(query.asc()).isTrue();
}
@Test