]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-5393 Fail to upgrade to SQ 4.3 + MySQL when millions of issues
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Mon, 16 Jun 2014 14:04:27 +0000 (16:04 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Mon, 16 Jun 2014 14:04:33 +0000 (16:04 +0200)
sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java
sonar-server/src/main/java/org/sonar/server/db/migrations/v43/IssueMigration.java
sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java
sonar-server/src/test/resources/org/sonar/server/db/migrations/MassUpdaterTest/ignore_null_rows.xml [new file with mode: 0644]

index 34d47f05e498692298a4b6aafdb1b5fb9cb698db..a43f2a04a6e67655fe85e5bb8be5b86b35ea15b7 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.utils.MessageException;
 import org.sonar.core.persistence.Database;
 import org.sonar.core.persistence.dialect.MySql;
 
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 
 import java.sql.Connection;
@@ -59,6 +60,7 @@ public class MassUpdater {
   public static interface InputLoader<S> {
     String selectSql();
 
+    @CheckForNull
     S load(ResultSet rs) throws SQLException;
   }
 
@@ -108,7 +110,11 @@ public class MassUpdater {
 
       int cursor = 0;
       while (rs.next()) {
-        if (converter.convert(inputLoader.load(rs), writeStatement)) {
+        S row = inputLoader.load(rs);
+        if (row == null) {
+          continue;
+        }
+        if (converter.convert(row, writeStatement)) {
           writeStatement.addBatch();
           writeStatement.clearParameters();
           cursor++;
index c34e0c419eb9ce75b3e6296d153f2e356cdb2407..019c3c0ecfbded8f994f7a3c7ac503699b34754f 100644 (file)
@@ -60,15 +60,22 @@ public class IssueMigration implements DatabaseMigration {
       new MassUpdater.InputLoader<Row>() {
         @Override
         public String selectSql() {
-          return "SELECT i.id, i.technical_debt FROM issues i WHERE i.technical_debt IS NOT NULL";
+          return "SELECT i.id, i.technical_debt FROM issues i";
         }
 
         @Override
         public Row load(ResultSet rs) throws SQLException {
-          Row row = new Row();
-          row.id = SqlUtil.getLong(rs, 1);
-          row.debt = SqlUtil.getLong(rs, 2);
-          return row;
+          Long debt = SqlUtil.getLong(rs, 2);
+          if (!rs.wasNull() && debt != null) {
+            // See https://jira.codehaus.org/browse/SONAR-5394
+            // The SQL request should not set the filter on technical_debt is not null. There's no index
+            // on this column, so filtering is done programmatically.
+            Row row = new Row();
+            row.id = SqlUtil.getLong(rs, 1);
+            row.debt = debt;
+            return row;
+          }
+          return null;
         }
       },
       new MassUpdater.InputConverter<Row>() {
index f5aaeb81aed9d32e69a40acee6e9e3d8167e72fc..36a9085cf323b307002bc678ec74d193a419c42e 100644 (file)
@@ -79,7 +79,7 @@ public class MassUpdaterTest {
           return true;
         }
       }
-    );
+      );
 
     db.assertDbUnit(getClass(), "migrate_data_result.xml", "issues");
   }
@@ -112,7 +112,7 @@ public class MassUpdaterTest {
             return true;
           }
         }
-      );
+        );
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(MessageException.class);
@@ -149,13 +149,47 @@ public class MassUpdaterTest {
             return true;
           }
         }
-      );
+        );
       fail();
     } catch (Exception e) {
       assertThat(e).isInstanceOf(MessageException.class);
     }
   }
 
+  @Test
+  public void ignore_null_rows() throws Exception {
+    db.prepareDbUnit(getClass(), "ignore_null_rows.xml");
+
+    new MassUpdater(db.database()).execute(
+      new MassUpdater.InputLoader<Row>() {
+        @Override
+        public String selectSql() {
+          return "SELECT i.id FROM issues i";
+        }
+
+        @Override
+        public Row load(ResultSet rs) throws SQLException {
+          return null;
+        }
+      },
+      new MassUpdater.InputConverter<Row>() {
+        @Override
+        public String updateSql() {
+          return "UPDATE issues SET severity=? WHERE id=?";
+        }
+
+        @Override
+        public boolean convert(Row row, PreparedStatement updateStatement) throws SQLException {
+          updateStatement.setString(1, "BLOCKER");
+          updateStatement.setLong(2, row.id);
+          return true;
+        }
+      }
+      );
+    // no changes, do not set severity to BLOCKER
+    db.assertDbUnit(getClass(), "ignore_null_rows.xml", "issues");
+  }
+
   @Test
   public void convert_select_sql() throws Exception {
     Database db = mock(Database.class);
diff --git a/sonar-server/src/test/resources/org/sonar/server/db/migrations/MassUpdaterTest/ignore_null_rows.xml b/sonar-server/src/test/resources/org/sonar/server/db/migrations/MassUpdaterTest/ignore_null_rows.xml
new file mode 100644 (file)
index 0000000..5eb657b
--- /dev/null
@@ -0,0 +1,10 @@
+<dataset>
+
+  <issues ID="1" COMPONENT_ID="11" ROOT_COMPONENT_ID="10" RULE_ID="20" SEVERITY="MINOR" KEE="1"
+          ACTION_PLAN_KEY="[null]" ASSIGNEE="[null]" AUTHOR_LOGIN="[null]" CHECKSUM="ABCDE"
+          EFFORT_TO_FIX="3.14" ISSUE_ATTRIBUTES="[null]" ISSUE_CLOSE_DATE="[null]" ISSUE_CREATION_DATE="2012-01-05"
+          ISSUE_UPDATE_DATE="2012-01-05" LINE="1234" MANUAL_SEVERITY="[false]" MESSAGE="the message" REPORTER="[null]"
+          RESOLUTION="[null]" STATUS="OPEN" CREATED_AT="2012-01-05" UPDATED_AT="2012-01-05"
+          TECHNICAL_DEBT="10"/>
+
+</dataset>