From b16df65ced9a3882f368d30ac729d5593f6ac8db Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Mon, 12 Aug 2013 12:27:03 +0200 Subject: [PATCH] SONAR-4563 Use strict comparison for createdAfter in the Issues search engine --- .../issue/notification/NewIssuesEmailTemplate.java | 2 +- .../notification/NewIssuesEmailTemplateTest.java | 2 +- .../org/sonar/core/issue/db/IssueMapper.xml | 3 +++ .../java/org/sonar/core/issue/db/IssueDaoTest.java | 7 ++++++- .../IssueDaoTest/should_select_by_date_creation.xml | 2 +- .../main/java/org/sonar/api/issue/IssueQuery.java | 13 +++++++++++++ .../java/org/sonar/api/issue/RubyIssueService.java | 4 +++- .../sonar/server/issue/IssueFilterParameters.java | 1 + .../sonar/server/issue/PublicRubyIssueService.java | 1 + 9 files changed, 30 insertions(+), 5 deletions(-) diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplate.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplate.java index d479c508d1f..fd3fc36711f 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplate.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplate.java @@ -68,7 +68,7 @@ public class NewIssuesEmailTemplate extends EmailTemplate { String dateString = notification.getFieldValue("projectDate"); if (projectKey != null && dateString != null) { Date date = DateUtils.parseDateTime(dateString); - String url = String.format("%s/issues/search?componentRoots=%s&createdAfter=%s", + String url = String.format("%s/issues/search?componentRoots=%s&createdAtOrAfter=%s", settings.getServerBaseURL(), encode(projectKey), encode(DateUtils.formatDateTime(date))); sb.append("\n").append("See it in SonarQube: ").append(url).append("\n"); } diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplateTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplateTest.java index eb09ae9c7d9..97f57cdf8d5 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplateTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/issue/notification/NewIssuesEmailTemplateTest.java @@ -73,7 +73,7 @@ public class NewIssuesEmailTemplateTest { "Project: Struts\n" + "32 new issues\n" + "\n" + - "See it in SonarQube: http://nemo.sonarsource.org/issues/search?componentRoots=org.apache%3Astruts&createdAfter=2010-05-18T16%3A50%3A45%2B0200\n"); + "See it in SonarQube: http://nemo.sonarsource.org/issues/search?componentRoots=org.apache%3Astruts&createdAtOrAfter=2010-05-18T16%3A50%3A45%2B0200\n"); } @Test 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 8e65de6406d..e2c55b4aa92 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 @@ -290,6 +290,9 @@ and i.issue_creation_date > #{query.createdAfter} + + and i.issue_creation_date >= #{query.createdAtOrAfter} + and i.issue_creation_date < #{query.createdBefore} 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 69ac592d896..b8fdb2977bc 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 @@ -120,8 +120,13 @@ public class IssueDaoTest extends AbstractDaoTestCase { public void should_select_by_date_creation() { setupData("shared", "should_select_by_date_creation"); - IssueQuery query = IssueQuery.builder().createdAfter(DateUtils.parseDate("2013-04-15")).requiredRole("user").build(); + IssueQuery query = IssueQuery.builder().createdAfter(DateUtils.parseDate("2013-04-15")).build(); assertThat(dao.selectIssueIds(query)).hasSize(1); + assertThat(dao.selectIssueIds(query).get(0).getId()).isEqualTo(100L); + + query = IssueQuery.builder().createdAtOrAfter(DateUtils.parseDate("2013-04-15")).build(); + assertThat(dao.selectIssueIds(query)).hasSize(1); + assertThat(dao.selectIssueIds(query).get(0).getId()).isEqualTo(100L); query = IssueQuery.builder().createdBefore(DateUtils.parseDate("2013-04-17")).requiredRole("user").build(); assertThat(dao.selectIssueIds(query)).hasSize(2); diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_date_creation.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_date_creation.xml index cd509c70d50..cf6048a5e83 100644 --- a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_date_creation.xml +++ b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueDaoTest/should_select_by_date_creation.xml @@ -18,7 +18,7 @@ assignee="perceval" author_login="[null]" issue_attributes="JIRA=FOO-1234" - issue_creation_date="2013-04-16" + issue_creation_date="2013-04-16 15:50:45" issue_update_date="2013-04-16" issue_close_date="2013-04-16" created_at="2013-04-16" diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java index 23e21d30ab6..d7ce899c4f8 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/IssueQuery.java @@ -70,6 +70,7 @@ public class IssueQuery { private final Boolean assigned; private final Boolean planned; private final Boolean resolved; + private final Date createdAtOrAfter; private final Date createdAfter; private final Date createdBefore; private final String sort; @@ -96,6 +97,7 @@ public class IssueQuery { this.assigned = builder.assigned; this.planned = builder.planned; this.resolved = builder.resolved; + this.createdAtOrAfter = builder.createdAtOrAfter; this.createdAfter = builder.createdAfter; this.createdBefore = builder.createdBefore; this.sort = builder.sort; @@ -165,6 +167,11 @@ public class IssueQuery { return (createdAfter == null ? null : new Date(createdAfter.getTime())); } + @CheckForNull + public Date createdAtOrAfter() { + return (createdAtOrAfter == null ? null : new Date(createdAtOrAfter.getTime())); + } + @CheckForNull public Date createdBefore() { return (createdBefore == null ? null : new Date(createdBefore.getTime())); @@ -219,6 +226,7 @@ public class IssueQuery { private Boolean assigned = null; private Boolean planned = null; private Boolean resolved = null; + private Date createdAtOrAfter; private Date createdAfter; private Date createdBefore; private String sort; @@ -307,6 +315,11 @@ public class IssueQuery { return this; } + public Builder createdAtOrAfter(@Nullable Date d) { + this.createdAtOrAfter = (d == null ? null : new Date(d.getTime())); + return this; + } + public Builder createdAfter(@Nullable Date d) { this.createdAfter = (d == null ? null : new Date(d.getTime())); return this; diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java b/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java index 440105e5787..1afd5e480ee 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/issue/RubyIssueService.java @@ -63,7 +63,9 @@ public interface RubyIssueService extends ServerComponent { *
  • 'reporters': list of reporter logins. Note that reporters are defined only on "manual" issues.
  • *
  • 'assignees': list of assignee logins.
  • *
  • 'assigned': true to get only assigned issues, false to get only unassigned issues. By default no filtering is done.
  • - *
  • 'createdAfter': match all the issues created after the given date (inclusive). + *
  • 'createdAfter': match all the issues created after the given date (strictly). + * Both date and datetime ISO formats are supported: 2013-05-18 or 2010-05-18T15:50:45+0100
  • + *
  • 'createdAtOrAfter': match all the issues created after the given date (inclusive). * Both date and datetime ISO formats are supported: 2013-05-18 or 2010-05-18T15:50:45+0100
  • *
  • 'createdBefore': match all the issues created before the given date (exclusive). * Both date and datetime ISO formats are supported: 2013-05-18 or 2010-05-18T15:50:45+0100
  • diff --git a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java b/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java index c4b6d9c92db..d1101062bf5 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/IssueFilterParameters.java @@ -47,6 +47,7 @@ public class IssueFilterParameters { public static final String ASSIGNED = "assigned"; public static final String PLANNED = "planned"; public static final String CREATED_AFTER = "createdAfter"; + public static final String CREATED_AT_OR_AFTER = "createdAtOrAfter"; public static final String CREATED_BEFORE = "createdBefore"; public static final String PAGE_SIZE = "pageSize"; public static final String PAGE_INDEX = "pageIndex"; diff --git a/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java b/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java index b7e7f616612..9f39ad2c2fe 100644 --- a/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java +++ b/sonar-server/src/main/java/org/sonar/server/issue/PublicRubyIssueService.java @@ -88,6 +88,7 @@ public class PublicRubyIssueService implements RubyIssueService { .assignees(RubyUtils.toStrings(props.get(IssueFilterParameters.ASSIGNEES))) .assigned(RubyUtils.toBoolean(props.get(IssueFilterParameters.ASSIGNED))) .planned(RubyUtils.toBoolean(props.get(IssueFilterParameters.PLANNED))) + .createdAtOrAfter(RubyUtils.toDate(props.get(IssueFilterParameters.CREATED_AT_OR_AFTER))) .createdAfter(RubyUtils.toDate(props.get(IssueFilterParameters.CREATED_AFTER))) .createdBefore(RubyUtils.toDate(props.get(IssueFilterParameters.CREATED_BEFORE))) .pageSize(RubyUtils.toInteger(props.get(IssueFilterParameters.PAGE_SIZE))) -- 2.39.5