import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.component.Component;
import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.issue.db.IssueDao;
import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import org.sonar.core.resource.ResourceDao;
-import org.sonar.server.rule.DefaultRuleFinder;
import org.sonar.server.issue.actionplan.ActionPlanService;
+import org.sonar.server.rule.DefaultRuleFinder;
import org.sonar.server.user.UserSession;
import javax.annotation.CheckForNull;
public IssueQueryResult find(IssueQuery query) {
LOG.debug("IssueQuery : {}", query);
long start = System.currentTimeMillis();
- SqlSession sqlSession = myBatis.openSession(false);
+ DbSession sqlSession = myBatis.openSession(false);
try {
// 1. Select the authorized ids of all the issues that match the query
List<IssueDto> authorizedIssues = issueDao.selectIssueIds(query, UserSession.get().userId(), sqlSession);
List<Transition> outTransitions = workflow.outTransitions(issue);
List<Transition> allowedTransitions = new ArrayList<Transition>();
for (Transition transition : outTransitions) {
- DefaultIssue defaultIssue = (DefaultIssue) issue;
- String projectKey = defaultIssue.projectKey();
+ String projectKey = issue.projectKey();
if (StringUtils.isBlank(transition.requiredProjectPermission()) ||
(projectKey != null && UserSession.get().hasProjectPermission(transition.requiredProjectPermission(), projectKey))) {
allowedTransitions.add(transition);
update.put(IssueField.RULE_KEY.field(), dto.getRuleKey().toString());
// TODO Not yet normalized
- // IssueDoc issueDoc = new IssueDoc(null);
- // issueDoc.isNew();
- // issueDoc.comments();
// issueDoc.attributes();
/** Upsert elements */
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.Issue;
import org.sonar.api.issue.action.Action;
-import org.sonar.api.issue.internal.DefaultIssue;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.web.UserRole;
import org.sonar.core.issue.workflow.Transition;
public void writeTransitions(Issue issue, JsonWriter json) {
json.name("transitions").beginArray();
if (UserSession.get().isLoggedIn()) {
- List<Transition> transitions = issueService.listTransitions(issue);
- for (Transition transition : transitions) {
+ for (Transition transition : issueService.listTransitions(issue)) {
json.value(transition.key());
}
}
public void writeActions(Issue issue, JsonWriter json) {
json.name("actions").beginArray();
- for (String action : actions((DefaultIssue) issue)) {
+ for (String action : actions(issue)) {
json.value(action);
}
json.endArray();
}
- private List<String> actions(DefaultIssue issue) {
+ private List<String> actions(Issue issue) {
List<String> actions = newArrayList();
String login = UserSession.get().login();
if (login != null) {
import com.google.common.base.Function;
import com.google.common.base.Strings;
+import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
import com.google.common.io.Resources;
import org.sonar.api.i18n.I18n;
-import org.sonar.api.issue.*;
+import org.sonar.api.issue.ActionPlan;
+import org.sonar.api.issue.Issue;
+import org.sonar.api.issue.IssueComment;
+import org.sonar.api.issue.IssueQuery;
+import org.sonar.api.issue.internal.DefaultIssueComment;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.ws.Request;
import org.sonar.api.utils.text.JsonWriter;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
+import org.sonar.core.issue.db.IssueChangeDao;
import org.sonar.core.persistence.DbSession;
import org.sonar.markdown.Markdown;
import org.sonar.server.db.DbClient;
import java.util.*;
import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.Sets.newHashSet;
public class SearchAction extends SearchRequestHandler<IssueQuery, Issue> {
private static final String EXTRA_FIELDS_PARAM = "extra_fields";
+ private final IssueChangeDao issueChangeDao;
private final IssueService service;
private final IssueActionsWriter actionsWriter;
private final I18n i18n;
private final Durations durations;
- public SearchAction(IssueService service, IssueActionsWriter actionsWriter, RuleService ruleService, DbClient dbClient,
+ public SearchAction(DbClient dbClient, IssueChangeDao issueChangeDao, IssueService service, IssueActionsWriter actionsWriter, RuleService ruleService,
ActionPlanService actionPlanService, UserFinder userFinder, I18n i18n, Durations durations) {
super(SEARCH_ACTION);
+ this.dbClient = dbClient;
+ this.issueChangeDao = issueChangeDao;
this.service = service;
this.actionsWriter = actionsWriter;
this.ruleService = ruleService;
- this.dbClient = dbClient;
this.actionPlanService = actionPlanService;
this.userFinder = userFinder;
this.i18n = i18n;
@Override
protected Result<Issue> doSearch(IssueQuery query, QueryContext context) {
- return ((DefaultIssueService)service).search(query, context);
- }
-
- @Override
- protected void doResultResponse(Request request, QueryContext context, Result<Issue> result, JsonWriter json) {
- writeIssues(result, request.paramAsStrings(EXTRA_FIELDS_PARAM), json);
+ return ((DefaultIssueService) service).search(query, context);
}
@Override
@Override
protected void doContextResponse(Request request, QueryContext context, Result<Issue> result, JsonWriter json) {
- // Insert the projects and component name;
- Set<RuleKey> ruleKeys = new HashSet<RuleKey>();
- Set<String> projectKeys = new HashSet<String>();
- Set<String> componentKeys = new HashSet<String>();
- Set<String> actionPlanKeys = new HashSet<String>();
- List<String> userLogins = new ArrayList<String>();
+ List<String> issueKeys = newArrayList();
+ Set<RuleKey> ruleKeys = newHashSet();
+ Set<String> projectKeys = newHashSet();
+ Set<String> componentKeys = newHashSet();
+ Set<String> actionPlanKeys = newHashSet();
+ List<String> userLogins = newArrayList();
+ Map<String, User> usersByLogin = newHashMap();
+ Multimap<String, DefaultIssueComment> commentsByIssues = ArrayListMultimap.create();
for (Issue issue : result.getHits()) {
+ issueKeys.add(issue.key());
ruleKeys.add(issue.ruleKey());
projectKeys.add(issue.projectKey());
componentKeys.add(issue.componentKey());
actionPlanKeys.add(issue.actionPlanKey());
- userLogins.add(issue.authorLogin());
+ if (issue.reporter() != null) {
+ userLogins.add(issue.reporter());
+ }
+ if (issue.assignee() != null) {
+ userLogins.add(issue.assignee());
+ }
}
- writeRules(json, !request.mandatoryParamAsBoolean(IssueFilterParameters.HIDE_RULES) ? ruleService.getByKeys(ruleKeys) : Collections.<Rule>emptyList());
- writeUsers(json, userFinder.findByLogins(userLogins));
- writeActionPlans(json, actionPlanService.findByKeys(actionPlanKeys));
-
DbSession session = dbClient.openSession(false);
try {
+ List<DefaultIssueComment> comments = issueChangeDao.selectCommentsByIssues(session, issueKeys);
+ for (DefaultIssueComment issueComment : comments) {
+ userLogins.add(issueComment.userLogin());
+ commentsByIssues.put(issueComment.issueKey(), issueComment);
+ }
+ usersByLogin = getUsersByLogin(session, userLogins);
+
List<ComponentDto> componentDtos = dbClient.componentDao().getByKeys(session, componentKeys);
List<ComponentDto> projectDtos = dbClient.componentDao().getByKeys(session, projectKeys);
+
componentDtos.addAll(projectDtos);
writeProjects(json, projectDtos);
writeComponents(json, componentDtos);
session.close();
}
+ Map<String, ActionPlan> actionPlanByKeys = getActionPlanByKeys(actionPlanKeys);
+
+ writeIssues(result, commentsByIssues, usersByLogin, actionPlanByKeys, request.paramAsStrings(EXTRA_FIELDS_PARAM), json);
+ writeRules(json, !request.mandatoryParamAsBoolean(IssueFilterParameters.HIDE_RULES) ? ruleService.getByKeys(ruleKeys) : Collections.<Rule>emptyList());
+ writeUsers(json, usersByLogin);
+ writeActionPlans(json, actionPlanByKeys.values());
+
// TODO remove legacy paging. Handled by the SearchRequestHandler
writeLegacyPaging(context, json, result);
}
json.endArray();
}
- private void writeIssues(Result<Issue> result, @Nullable List<String> extraFields, JsonWriter json) {
+ private void writeIssues(Result<Issue> result, Multimap<String, DefaultIssueComment> commentsByIssues, Map<String, User> usersByLogin, Map<String, ActionPlan> actionPlanByKeys,
+ @Nullable List<String> extraFields, JsonWriter json) {
json.name("issues").beginArray();
for (Issue issue : result.getHits()) {
.prop("fUpdateAge", formatAgeDate(updateDate))
.prop("closeDate", isoDate(issue.closeDate()));
- // TODO add comments
- // writeIssueComments(result, issue, json);
+ writeIssueComments(commentsByIssues.get(issue.key()), usersByLogin, json);
writeIssueAttributes(issue, json);
- // TODO Add fields
- // writeIssueExtraFields(result, issue, extraFields, json);
+ writeIssueExtraFields(issue, usersByLogin, actionPlanByKeys, extraFields, json);
json.endObject();
}
json.endArray();
}
- private void writeIssueComments(IssueQueryResult queryResult, Issue issue, JsonWriter json) {
- if (!issue.comments().isEmpty()) {
+ private void writeIssueComments(Collection<DefaultIssueComment> issueComments, Map<String, User> usersByLogin, JsonWriter json) {
+ if (!issueComments.isEmpty()) {
json.name("comments").beginArray();
String login = UserSession.get().login();
- for (IssueComment comment : issue.comments()) {
+ for (IssueComment comment : issueComments) {
String userLogin = comment.userLogin();
- User user = userLogin != null ? queryResult.user(userLogin) : null;
+ User user = userLogin != null ? usersByLogin.get(userLogin) : null;
json.beginObject()
.prop("key", comment.key())
.prop("login", comment.userLogin())
}
}
- private void writeIssueExtraFields(IssueQueryResult result, Issue issue, @Nullable List<String> extraFields, JsonWriter json) {
+ private void writeIssueExtraFields(Issue issue, Map<String, User> usersByLogin, Map<String, ActionPlan> actionPlanByKeys, @Nullable List<String> extraFields, JsonWriter json) {
if (extraFields != null && UserSession.get().isLoggedIn()) {
if (extraFields.contains(ACTIONS_EXTRA_FIELD)) {
actionsWriter.writeActions(issue, json);
String assignee = issue.assignee();
if (extraFields.contains(ASSIGNEE_NAME_EXTRA_FIELD) && assignee != null) {
- User user = result.user(assignee);
+ User user = usersByLogin.get(assignee);
json.prop(ASSIGNEE_NAME_EXTRA_FIELD, user != null ? user.name() : null);
}
String reporter = issue.reporter();
if (extraFields.contains(REPORTER_NAME_EXTRA_FIELD) && reporter != null) {
- User user = result.user(reporter);
+ User user = usersByLogin.get(reporter);
json.prop(REPORTER_NAME_EXTRA_FIELD, user != null ? user.name() : null);
}
String actionPlanKey = issue.actionPlanKey();
if (extraFields.contains(ACTION_PLAN_NAME_EXTRA_FIELD) && actionPlanKey != null) {
- ActionPlan actionPlan = result.actionPlan(issue);
+ ActionPlan actionPlan = actionPlanByKeys.get(actionPlanKey);
json.prop(ACTION_PLAN_NAME_EXTRA_FIELD, actionPlan != null ? actionPlan.name() : null);
}
}
json.endArray();
}
- private void writeUsers(JsonWriter json, List<User> users) {
+ private void writeUsers(JsonWriter json, Map<String, User> usersByLogin) {
json.name("users").beginArray();
- for (User user : users) {
+ for (User user : usersByLogin.values()) {
json.beginObject()
.prop("login", user.login())
.prop("name", user.name())
json.endArray();
}
- private void writeActionPlans(JsonWriter json, List<ActionPlan> plans) {
+ private void writeActionPlans(JsonWriter json, Collection<ActionPlan> plans) {
if (!plans.isEmpty()) {
json.name("actionPlans").beginArray();
for (ActionPlan actionPlan : plans) {
}
}
+ private Map<String, User> getUsersByLogin(DbSession session, List<String> userLogins) {
+ Map<String, User> usersByLogin = newHashMap();
+ for (User user : userFinder.findByLogins(userLogins)) {
+ usersByLogin.put(user.login(), user);
+ }
+ return usersByLogin;
+ }
+
+ private Map<String, ActionPlan> getActionPlanByKeys(Collection<String> actionPlanKeys) {
+ Map<String, ActionPlan> actionPlans = newHashMap();
+ for (ActionPlan actionPlan : actionPlanService.findByKeys(actionPlanKeys)) {
+ actionPlans.put(actionPlan.key(), actionPlan);
+ }
+ return actionPlans;
+ }
+
@CheckForNull
private String isoDate(@Nullable Date date) {
if (date != null) {
protected abstract QUERY doQuery(Request request);
- protected abstract void doResultResponse(Request request, QueryContext context, Result<DOMAIN> result, JsonWriter json);
-
protected abstract void doContextResponse(Request request, QueryContext context, Result<DOMAIN> result, JsonWriter json);
protected abstract void doDefinition(WebService.NewAction action);
JsonWriter json = response.newJsonWriter().beginObject();
this.writeStatistics(json, result, context);
- doResultResponse(request, context, result, json);
doContextResponse(request, context, result, json);
if (context.isFacet()) {
writeFacets(result, json);
import org.sonar.api.utils.DateUtils;
import org.sonar.api.web.UserRole;
import org.sonar.core.component.ComponentDto;
-import org.sonar.core.issue.db.IssueDto;
+import org.sonar.core.issue.db.*;
import org.sonar.core.permission.PermissionFacade;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.rule.RuleDto;
tester.get(RuleDao.class).insert(session, rule);
project = new ComponentDto()
- .setId(1L)
- .setKey("MyProject")
- .setProjectId(1L);
+ .setKey("MyProject");
db.componentDao().insert(session, project);
db.snapshotDao().insert(session, SnapshotTesting.createForComponent(project));
db.issueAuthorizationDao().synchronizeAfter(session, new Date(0));
file = new ComponentDto()
- .setProjectId(1L)
.setKey("MyComponent")
- .setId(2L);
+ .setProjectId(project.getId());
db.componentDao().insert(session, file);
db.snapshotDao().insert(session, SnapshotTesting.createForComponent(file));
- UserDto john = new UserDto().setLogin("john").setName("John").setEmail("john@email.com").setActive(true);
+ UserDto john = new UserDto().setLogin("john").setName("John").setEmail("john@email.com");
db.userDao().insert(session, john);
session.commit();
- MockUserSession.set().setLogin("gandalf");
+ MockUserSession.set().setLogin("john");
}
@After
}
@Test
- public void find_single_result() throws Exception {
+ public void issue() throws Exception {
+ db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com"));
+ db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+
IssueDto issue = IssueTesting.newDto(rule, file, project)
- .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
- .setIssueUpdateDate(DateUtils.parseDate("2014-12-04"))
.setRule(rule)
.setDebt(10L)
.setRootComponent(project)
.setStatus("OPEN").setResolution("OPEN")
.setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
.setSeverity("MAJOR")
- .setAuthorLogin("john");
+ .setAuthorLogin("John")
+ .setAssignee("simon")
+ .setReporter("fabrice")
+ .setActionPlanKey("AP-ABCD")
+ .setIssueCreationDate(DateUtils.parseDate("2014-09-04"))
+ .setIssueUpdateDate(DateUtils.parseDate("2014-12-04"));
db.issueDao().insert(session, issue);
session.commit();
- WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
+ WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
+ // TODO date assertion is complex to test, and components id are not predictable, that's why strict boolean is set to false
+ result.assertJson(this.getClass(), "issue.json", false);
+ }
- WsTester.Result result = request.execute();
- // TODO Date assertion is complex to test
- result.assertJson(this.getClass(), "single_result.json", false);
+ @Test
+ public void issue_with_comment() throws Exception {
+ db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+
+ IssueDto issue = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2");
+ db.issueDao().insert(session, issue);
+
+ tester.get(IssueChangeDao.class).insert(session,
+ new IssueChangeDto().setIssueKey(issue.getKey())
+ .setKey("COMMENT-ABCD")
+ .setChangeData("*My comment*")
+ .setChangeType(IssueChangeDto.TYPE_COMMENT)
+ .setUserLogin("john")
+ .setCreatedAt(DateUtils.parseDate("2014-09-09")));
+ tester.get(IssueChangeDao.class).insert(session,
+ new IssueChangeDto().setIssueKey(issue.getKey())
+ .setKey("COMMENT-ABCE")
+ .setChangeData("Another comment")
+ .setChangeType(IssueChangeDto.TYPE_COMMENT)
+ .setUserLogin("fabrice")
+ .setCreatedAt(DateUtils.parseDate("2014-09-10")));
+ session.commit();
+
+ WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
+ result.assertJson(this.getClass(), "issue_with_comment.json", false);
+ }
+
+ @Test
+ public void issue_with_action_plan() throws Exception {
+ db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com"));
+ db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+
+ tester.get(ActionPlanDao.class).save(new ActionPlanDto()
+ .setKey("AP-ABCD")
+ .setName("1.0")
+ .setStatus("OPEN")
+ .setProjectId(project.getId())
+ .setUserLogin("simon")
+ .setDeadLine(DateUtils.parseDateTime("2014-01-24T19:10:03+0100"))
+ .setCreatedAt(DateUtils.parseDateTime("2014-01-22T19:10:03+0100"))
+ .setUpdatedAt(DateUtils.parseDateTime("2014-01-23T19:10:03+0100")));
+
+ IssueDto issue = IssueTesting.newDto(rule, file, project).setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
+ .setActionPlanKey("AP-ABCD");
+ db.issueDao().insert(session, issue);
+ session.commit();
+
+ WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).execute();
+ result.assertJson(this.getClass(), "issue_with_action_plan.json", false);
+ }
+
+ @Test
+ public void issue_with_extra_fields() throws Exception {
+ db.userDao().insert(session, new UserDto().setLogin("simon").setName("Simon").setEmail("simon@email.com"));
+ db.userDao().insert(session, new UserDto().setLogin("fabrice").setName("Fabrice").setEmail("fabrice@email.com"));
+
+ tester.get(ActionPlanDao.class).save(new ActionPlanDto()
+ .setKey("AP-ABCD")
+ .setName("1.0")
+ .setStatus("OPEN")
+ .setProjectId(project.getId())
+ .setUserLogin("simon"));
+
+ IssueDto issue = IssueTesting.newDto(rule, file, project)
+ .setKee("82fd47d4-b650-4037-80bc-7b112bd4eac2")
+ .setAuthorLogin("John")
+ .setAssignee("simon")
+ .setReporter("fabrice")
+ .setActionPlanKey("AP-ABCD");
+ db.issueDao().insert(session, issue);
+ session.commit();
+
+ WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION)
+ .setParam("extra_fields", "actions,transitions,assigneeName,reporterName,actionPlanName").execute();
+ result.assertJson(this.getClass(), "issue_with_extra_fields.json", false);
}
@Test
db.issueDao().insert(session, issue);
session.commit();
- WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
- request.setParam(SearchAction.PARAM_FACETS, "true");
-
- WsTester.Result result = request.execute();
+ WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(SearchAction.PARAM_FACETS, "true").execute();
result.assertJson(this.getClass(), "display_facets.json", false);
}
db.issueDao().insert(session, issue);
session.commit();
- WsTester.TestRequest request = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION);
- request.setParam(IssueFilterParameters.HIDE_RULES, "true");
-
- WsTester.Result result = request.execute();
+ WsTester.Result result = wsTester.newGetRequest(IssuesWs.API_ENDPOINT, SearchAction.SEARCH_ACTION).setParam(IssueFilterParameters.HIDE_RULES, "true").execute();
result.assertJson(this.getClass(), "hide_rules.json", false);
}
--- /dev/null
+{
+ "maxResultsReached": false,
+ "total": 1,
+ "p": 1,
+ "ps": 100,
+ "issues": [
+ {
+ "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+ "component": "MyComponent",
+ "project": "MyProject",
+ "rule": "xoo:x1",
+ "status": "OPEN",
+ "resolution": "OPEN",
+ "severity": "MAJOR",
+ "debt": "10min",
+ "author": "John",
+ "assignee": "simon",
+ "reporter": "fabrice",
+ "actionPlan": "AP-ABCD",
+ "updateDate": "2014-12-04T00:00:00+0100",
+ "fUpdateAge": "less than a minute"
+ }
+ ],
+ "rules": [
+ {
+ "key": "xoo:x1",
+ "name": "Rule name",
+ "desc": "Rule desc",
+ "status": "READY"
+ }
+ ],
+ "components": [
+ {
+ "key": "MyComponent"
+ },
+ {
+ "key": "MyProject"
+ }
+ ],
+ "projects": [
+ {
+ "key": "MyProject"
+ }
+ ],
+ "users": [
+ {
+ "login": "simon",
+ "name": "Simon",
+ "active": true,
+ "email": "simon@email.com"
+ },
+ {
+ "login": "fabrice",
+ "name": "Fabrice",
+ "active": true,
+ "email": "fabrice@email.com"
+ }
+ ]
+}
--- /dev/null
+{
+ "issues": [
+ {
+ "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+ "actionPlan": "AP-ABCD"
+ }
+ ],
+ "actionPlans": [
+ {
+ "key": "AP-ABCD",
+ "name": "1.0",
+ "status": "OPEN",
+ "project": "MyProject",
+ "userLogin": "simon",
+ "deadLine": "2014-01-24T19:10:03+0100",
+ "fDeadLine": "Jan 24, 2014 7:10 PM",
+ "createdAt": "2014-01-22T19:10:03+0100",
+ "fCreatedAt": "Jan 22, 2014 7:10 PM",
+ "updatedAt": "2014-01-23T19:10:03+0100",
+ "fUpdatedAt": "Jan 23, 2014 7:10 PM"
+ }
+ ]
+}
--- /dev/null
+{
+ "issues": [
+ {
+ "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+ "comments": [
+ {
+ "key": "COMMENT-ABCD",
+ "login": "john",
+ "userName": "John",
+ "htmlText": "<em>My comment</em>",
+ "markdown": "*My comment*",
+ "updatable": true
+ },
+ {
+ "key": "COMMENT-ABCE",
+ "login": "fabrice",
+ "userName": "Fabrice",
+ "htmlText": "Another comment",
+ "markdown": "Another comment",
+ "updatable": false
+ }
+ ]
+ }
+ ]
+}
--- /dev/null
+{
+ "issues": [
+ {
+ "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
+ "assignee": "simon",
+ "assigneeName": "Simon",
+ "reporter": "fabrice",
+ "reporterName": "Fabrice",
+ "actionPlan": "AP-ABCD",
+ "actionPlanName": "1.0",
+ "actions": [
+ "comment", "assign", "assign_to_me", "plan"
+ ],
+ "transitions": [
+ "confirm", "resolve"
+ ]
+ }
+ ]
+}
+++ /dev/null
-{
- "maxResultsReached": false,
- "total": 1,
- "p": 1,
- "ps": 100,
- "issues": [
- {
- "key": "82fd47d4-b650-4037-80bc-7b112bd4eac2",
- "component": "MyComponent",
- "project": "MyProject",
- "rule": "xoo:x1",
- "status": "OPEN",
- "resolution": "OPEN",
- "severity": "MAJOR",
- "debt": "10min",
- "author": "john",
- "fUpdateAge": "less than a minute"
- }
- ],
- "rules": [
- {
- "key": "xoo:x1",
- "name": "Rule name",
- "desc": "Rule desc",
- "status": "READY"
- }
- ],
- "components": [
- {
- "key": "MyComponent",
- "id": 2
- },
- {
- "key": "MyProject",
- "id": 1
- }
- ],
- "projects": [
- {
- "key": "MyProject",
- "id": 1
- }
- ],
- "users": [
- {
- "login": "john",
- "name": "John",
- "active": true,
- "email": "john@email.com"
- }
- ]
-}
import com.google.common.collect.Lists;
import org.apache.ibatis.session.ResultHandler;
-import org.apache.ibatis.session.SqlSession;
import org.sonar.api.BatchComponent;
import org.sonar.api.ServerComponent;
import org.sonar.api.issue.internal.DefaultIssueComment;
import org.sonar.api.issue.internal.FieldDiffs;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import javax.annotation.CheckForNull;
this.mybatis = mybatis;
}
- public List<DefaultIssueComment> selectCommentsByIssues(SqlSession session, Collection<String> issueKeys) {
+ public List<DefaultIssueComment> selectCommentsByIssues(DbSession session, Collection<String> issueKeys) {
List<DefaultIssueComment> comments = Lists.newArrayList();
for (IssueChangeDto dto : selectByIssuesAndType(session, issueKeys, IssueChangeDto.TYPE_COMMENT)) {
comments.add(dto.toComment());
}
public List<FieldDiffs> selectChangelogByIssue(String issueKey) {
- SqlSession session = mybatis.openSession(false);
+ DbSession session = mybatis.openSession(false);
try {
List<FieldDiffs> result = Lists.newArrayList();
for (IssueChangeDto dto : selectByIssuesAndType(session, Arrays.asList(issueKey), IssueChangeDto.TYPE_FIELD_CHANGE)) {
}
public void selectChangelogOnNonClosedIssuesByModuleAndType(Integer componentId, ResultHandler handler) {
- SqlSession session = mybatis.openSession(false);
+ DbSession session = mybatis.openSession(false);
try {
Map<String, Object> params = newHashMap();
params.put("componentId", componentId);
@CheckForNull
public DefaultIssueComment selectCommentByKey(String commentKey) {
- SqlSession session = mybatis.openSession(false);
+ DbSession session = mybatis.openSession(false);
try {
IssueChangeMapper mapper = session.getMapper(IssueChangeMapper.class);
IssueChangeDto dto = mapper.selectByKeyAndType(commentKey, IssueChangeDto.TYPE_COMMENT);
}
}
- List<IssueChangeDto> selectByIssuesAndType(SqlSession session, Collection<String> issueKeys, String changeType) {
+ List<IssueChangeDto> selectByIssuesAndType(DbSession session, Collection<String> issueKeys, String changeType) {
if (issueKeys.isEmpty()) {
return Collections.emptyList();
}
return dtosList;
}
+ public void insert(DbSession session, IssueChangeDto change) {
+ session.getMapper(IssueChangeMapper.class).insert(change);
+ }
+
public boolean delete(String key) {
- SqlSession session = mybatis.openSession(false);
+ DbSession session = mybatis.openSession(false);
try {
IssueChangeMapper mapper = session.getMapper(IssueChangeMapper.class);
int count = mapper.delete(key);
}
public boolean update(IssueChangeDto change) {
- SqlSession session = mybatis.openSession(false);
+ DbSession session = mybatis.openSession(false);
try {
IssueChangeMapper mapper = session.getMapper(IssueChangeMapper.class);
int count = mapper.update(change);
package org.sonar.core.issue.db;
import org.apache.ibatis.executor.result.DefaultResultHandler;
-import org.apache.ibatis.session.SqlSession;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.issue.internal.DefaultIssueComment;
import org.sonar.api.issue.internal.FieldDiffs;
import org.sonar.api.utils.DateUtils;
import org.sonar.core.persistence.AbstractDaoTestCase;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.persistence.MyBatis;
import java.util.Arrays;
public class IssueChangeDaoTest extends AbstractDaoTestCase {
+ DbSession session;
+
IssueChangeDao dao;
@Before
- public void setUp() {
+ public void createDao() {
+ session = getMyBatis().openSession(false);
dao = new IssueChangeDao(getMyBatis());
}
+ @After
+ public void tearDown() throws Exception {
+ session.close();
+ }
+
@Test
public void select_comments_by_issues() {
setupData("shared");
- SqlSession session = getMyBatis().openSession();
+ DbSession session = getMyBatis().openSession(false);
List<DefaultIssueComment> comments = dao.selectCommentsByIssues(session, Arrays.asList("1000"));
MyBatis.closeQuietly(session);
assertThat(comments).hasSize(2);
public void select_comments_by_issues_on_huge_number_of_issues() {
setupData("shared");
- SqlSession session = getMyBatis().openSession();
+ DbSession session = getMyBatis().openSession(false);
List<String> hugeNbOfIssues = newArrayList();
for (int i=0; i<4500; i++) {
hugeNbOfIssues.add("ABCD"+i);
@Test
public void select_comments_by_issues_empty_input() {
// no need to connect to db
- SqlSession session = mock(SqlSession.class);
+ DbSession session = mock(DbSession.class);
List<DefaultIssueComment> comments = dao.selectCommentsByIssues(session, Collections.<String>emptyList());
assertThat(comments).isEmpty();
assertThat(dao.delete("UNKNOWN")).isFalse();
}
+ @Test
+ public void insert() {
+ setupData("empty");
+
+ IssueChangeDto changeDto = new IssueChangeDto()
+ .setKey("EFGH")
+ .setUserLogin("emmerik")
+ .setChangeData("Some text")
+ .setChangeType("comment")
+ .setIssueKey("ABCDE")
+ .setCreatedAt(DateUtils.parseDate("2014-09-09"))
+ .setUpdatedAt(DateUtils.parseDate("2014-09-10"))
+ .setIssueChangeCreationDate(DateUtils.parseDate("2014-09-11"));
+
+ dao.insert(session, changeDto);
+ session.commit();
+
+ checkTable("insert", "issue_changes");
+ }
+
@Test
public void update() {
setupData("update");
--- /dev/null
+<dataset>
+
+</dataset>
--- /dev/null
+<dataset>
+
+ <issue_changes
+ id="1"
+ kee="EFGH"
+ issue_key="ABCDE"
+ user_login="emmerik"
+ change_type="comment"
+ change_data="Some text"
+ created_at="2014-09-09"
+ updated_at="2014-09-10"
+ issue_change_creation_date="2014-09-11"
+ />
+
+</dataset>