diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-06-16 16:04:27 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-06-16 16:13:04 +0200 |
commit | 1bef404d75110e90aee36046b3f2ab526b1df0fa (patch) | |
tree | c5bd4961566c7557e1e6b2f56d33b24583916ffb | |
parent | dfc6cc8ea2fd04ff4eb428b11e75e4d4c279463d (diff) | |
download | sonarqube-1bef404d75110e90aee36046b3f2ab526b1df0fa.tar.gz sonarqube-1bef404d75110e90aee36046b3f2ab526b1df0fa.zip |
SONAR-5393 Fail to upgrade to SQ 4.3 + MySQL when millions of issues
4 files changed, 72 insertions, 10 deletions
diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java index 8ebb52612f6..0a54e07263c 100644 --- a/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java +++ b/sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java @@ -28,7 +28,13 @@ import org.sonar.api.utils.MessageException; import org.sonar.core.persistence.Database; import org.sonar.core.persistence.dialect.MySql; -import java.sql.*; + +import javax.annotation.CheckForNull; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; /** * Update a table by iterating a sub-set of rows. For each row a SQL UPDATE request @@ -47,6 +53,7 @@ public class MassUpdater { public static interface InputLoader<S> { String selectSql(); + @CheckForNull S load(ResultSet rs) throws SQLException; } @@ -85,7 +92,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(); cursor++; count++; diff --git a/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/IssueMigration.java b/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/IssueMigration.java index c34e0c419eb..019c3c0ecfb 100644 --- a/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/IssueMigration.java +++ b/sonar-server/src/main/java/org/sonar/server/db/migrations/v43/IssueMigration.java @@ -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>() { diff --git a/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java b/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java index f5aaeb81aed..36a9085cf32 100644 --- a/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java +++ b/sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java @@ -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,7 +149,7 @@ public class MassUpdaterTest { return true; } } - ); + ); fail(); } catch (Exception e) { assertThat(e).isInstanceOf(MessageException.class); @@ -157,6 +157,40 @@ public class MassUpdaterTest { } @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 index 00000000000..5eb657bf6a2 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/db/migrations/MassUpdaterTest/ignore_null_rows.xml @@ -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> |