aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2014-06-16 16:04:27 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2014-06-16 16:13:04 +0200
commit1bef404d75110e90aee36046b3f2ab526b1df0fa (patch)
treec5bd4961566c7557e1e6b2f56d33b24583916ffb
parentdfc6cc8ea2fd04ff4eb428b11e75e4d4c279463d (diff)
downloadsonarqube-1bef404d75110e90aee36046b3f2ab526b1df0fa.tar.gz
sonarqube-1bef404d75110e90aee36046b3f2ab526b1df0fa.zip
SONAR-5393 Fail to upgrade to SQ 4.3 + MySQL when millions of issues
-rw-r--r--sonar-server/src/main/java/org/sonar/server/db/migrations/MassUpdater.java15
-rw-r--r--sonar-server/src/main/java/org/sonar/server/db/migrations/v43/IssueMigration.java17
-rw-r--r--sonar-server/src/test/java/org/sonar/server/db/migrations/MassUpdaterTest.java40
-rw-r--r--sonar-server/src/test/resources/org/sonar/server/db/migrations/MassUpdaterTest/ignore_null_rows.xml10
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>