]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-4309 fix detection of conflicts
authorSimon Brandhof <simon.brandhof@gmail.com>
Tue, 4 Jun 2013 19:47:18 +0000 (21:47 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Tue, 4 Jun 2013 19:47:18 +0000 (21:47 +0200)
sonar-core/src/main/java/org/sonar/core/issue/db/IssueStorage.java
sonar-core/src/test/java/org/sonar/core/issue/db/IssueStorageTest.java
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_resolve_conflicts_on_updates-result.xml [new file with mode: 0644]
sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_resolve_conflicts_on_updates.xml [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/issue/internal/DefaultIssue.java

index bf4050312c0166859e340b3ae820b5670d3d6e3f..c8f657e5666b5b82a96742634c97611864816a4b 100644 (file)
@@ -27,11 +27,21 @@ import org.sonar.api.issue.internal.DefaultIssueComment;
 import org.sonar.api.issue.internal.FieldDiffs;
 import org.sonar.api.rules.Rule;
 import org.sonar.api.rules.RuleFinder;
+import org.sonar.core.persistence.BatchSession;
 import org.sonar.core.persistence.MyBatis;
 
 import java.util.Arrays;
 import java.util.Date;
 
+/**
+ * Save issues into database. It is executed :
+ * <ul>
+ * <li>once at the end of scan, even on multi-module projects</li>
+ * <li>on each server-side action initiated by UI or web service</li>
+ * </ul>
+ *
+ * @since 3.6
+ */
 public abstract class IssueStorage {
 
   private final MyBatis mybatis;
@@ -48,7 +58,10 @@ public abstract class IssueStorage {
   }
 
   public void save(Iterable<DefaultIssue> issues) {
+    // Batch session can not be used. It does not return the number of updated rows,
+    // required for detecting conflicts.
     SqlSession session = mybatis.openSession();
+    int count = 0;
     IssueMapper issueMapper = session.getMapper(IssueMapper.class);
     IssueChangeMapper issueChangeMapper = session.getMapper(IssueChangeMapper.class);
     Date now = new Date();
@@ -60,7 +73,9 @@ public abstract class IssueStorage {
           update(issueMapper, now, issue);
         }
         insertChanges(issueChangeMapper, issue);
-
+        if (count++> BatchSession.MAX_BATCH_SIZE) {
+          session.commit();
+        }
       }
       session.commit();
     } finally {
index b8744185375802f6867355091fc83dc621f119ca..1467b4f4490040f492ab0222835dbe613c5bb8f5 100644 (file)
@@ -109,6 +109,40 @@ public class IssueStorageTest extends AbstractDaoTestCase {
     checkTables("should_update_issues", new String[]{"id", "created_at", "updated_at"}, "issues", "issue_changes");
   }
 
+  @Test
+  public void should_resolve_conflicts_on_updates() throws Exception {
+    setupData("should_resolve_conflicts_on_updates");
+
+    FakeSaver saver = new FakeSaver(getMyBatis(), new FakeRuleFinder());
+
+    Date date = DateUtils.parseDate("2013-05-18");
+    DefaultIssue issue = new DefaultIssue()
+      .setKey("ABCDE")
+      .setNew(false)
+      .setChanged(true)
+      .setCreationDate(DateUtils.parseDate("2005-05-12"))
+      .setUpdateDate(date)
+      .setRuleKey(RuleKey.of("squid", "AvoidCycles"))
+      .setComponentKey("struts:Action")
+
+        // issue in database has been updated in 2013, after the loading by scan
+      .setSelectedAt(DateUtils.parseDate("2005-01-01"))
+
+        // fields to be updated
+      .setLine(444)
+      .setSeverity("BLOCKER")
+      .setChecksum("FFFFF")
+
+        // fields overridden by end-user -> do not save
+      .setAssignee("looser")
+      .setResolution(null)
+      .setStatus("REOPEN");
+
+    saver.save(issue);
+
+    checkTables("should_resolve_conflicts_on_updates", new String[]{"id", "created_at", "updated_at"}, "issues");
+  }
+
   static class FakeSaver extends IssueStorage {
     protected FakeSaver(MyBatis mybatis, RuleFinder ruleFinder) {
       super(mybatis, ruleFinder);
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_resolve_conflicts_on_updates-result.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_resolve_conflicts_on_updates-result.xml
new file mode 100644 (file)
index 0000000..05a2ea5
--- /dev/null
@@ -0,0 +1,51 @@
+<!--
+  ~ 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.
+  -->
+<dataset>
+  <rules id="200" name="Avoid Cycles" plugin_rule_key="AvoidCycles"
+         plugin_config_key="[null]" plugin_name="squid"/>
+
+  <projects id="10" scope="PRJ" qualifier="TRK" kee="struts" name="Struts"/>
+  <projects id="100" scope="FIL" qualifier="CLA" kee="struts:Action" name="Action"/>
+
+  <issues id="1"
+          kee="ABCDE"
+          resolution="FIXED"
+          status="RESOLVED"
+          severity="BLOCKER"
+          manual_severity="[false]"
+          assignee="winner"
+          author_login="[null]"
+          checksum="FFFFF"
+          effort_to_fix="[null]"
+          message="[null]"
+          line="444"
+          component_id="100"
+          root_component_id="10"
+          rule_id="200"
+          reporter="[null]"
+          issue_attributes=""
+          action_plan_key="[null]"
+          created_at="2005-05-12"
+          updated_at="2013-05-18"
+          issue_creation_date="2005-05-12 00:00:00.0"
+          issue_update_date="2013-05-18 00:00:00.0"
+          issue_close_date="[null]"
+    />
+</dataset>
\ No newline at end of file
diff --git a/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_resolve_conflicts_on_updates.xml b/sonar-core/src/test/resources/org/sonar/core/issue/db/IssueStorageTest/should_resolve_conflicts_on_updates.xml
new file mode 100644 (file)
index 0000000..c37f836
--- /dev/null
@@ -0,0 +1,53 @@
+<!--
+  ~ 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.
+  -->
+<dataset>
+
+  <rules id="200" name="Avoid Cycles" plugin_rule_key="AvoidCycles"
+         plugin_config_key="[null]" plugin_name="squid" />
+
+  <projects id="10" scope="PRJ" qualifier="TRK" kee="struts" name="Struts"/>
+  <projects id="100" scope="FIL" qualifier="CLA" kee="struts:Action" name="Action"/>
+
+
+  <issues id="1"
+          kee="ABCDE"
+          assignee="winner"
+          resolution="FIXED"
+          status="RESOLVED"
+          severity="MAJOR"
+          manual_severity="[false]"
+          author_login="[null]"
+          checksum="FFFFF"
+          effort_to_fix="[null]"
+          message="[null]"
+          line="1"
+          component_id="100"
+          root_component_id="10"
+          rule_id="200"
+          reporter="[null]"
+          issue_attributes=""
+          action_plan_key="[null]"
+          created_at="2005-05-12"
+          updated_at="2013-05-18"
+          issue_creation_date="2005-05-12 00:00:00.0"
+          issue_update_date="2013-05-18 00:00:00.0"
+          issue_close_date="[null]"
+    />
+</dataset>
\ No newline at end of file
index 1e86fd5004ac8f31d01add11d51f8c1d93152128..5ba60e544d1a8bd0a46487404df59a8aea284954 100644 (file)
@@ -392,8 +392,9 @@ public class DefaultIssue implements Issue {
     return selectedAt;
   }
 
-  public void setSelectedAt(@Nullable Date d) {
+  public DefaultIssue setSelectedAt(@Nullable Date d) {
     this.selectedAt = d;
+    return this;
   }
 
   @Override