import javax.annotation.CheckForNull;
import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
public byte[] getBytes(int columnIndex) throws SQLException {
return rs.getBytes(columnIndex);
}
+
+ @Override
+ public String toString() {
+ try {
+ ResultSetMetaData rsMetaData = rs.getMetaData();
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
+ if (i > 1) {
+ sb.append(",");
+ }
+ sb.append(rsMetaData.getColumnLabel(i).toLowerCase());
+ sb.append("=");
+ sb.append(rs.getObject(i));
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ return "Unavailable: " + e.getMessage();
+ }
+ }
}
static interface RowReader<T> {
rows.add(reader.read(row));
}
return rows;
+ } catch (Exception e) {
+ throw newExceptionWithRowDetails(row, e);
} finally {
DbUtils.closeQuietly(rs);
close();
return reader.read(row);
}
return null;
+ } catch (Exception e) {
+ throw newExceptionWithRowDetails(row, e);
} finally {
DbUtils.closeQuietly(rs);
close();
while (rs.next()) {
handler.handle(row);
}
+ } catch (Exception e) {
+ throw newExceptionWithRowDetails(row, e);
} finally {
DbUtils.closeQuietly(rs);
close();
}
}
+ private IllegalStateException newExceptionWithRowDetails(Select.Row row, Exception e) {
+ return new IllegalStateException("Error during processing of row: [" + row + "]", e);
+ }
+
static SelectImpl create(Database db, Connection connection, String sql) throws SQLException {
// TODO use DbClient#newScrollingSelectStatement()
PreparedStatement pstmt = connection.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
import org.codehaus.staxmate.in.SMInputCursor;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.KeyValueFormat;
-import org.sonar.api.utils.SonarException;
import org.sonar.api.utils.text.CsvWriter;
import javax.xml.stream.XMLInputFactory;
* Parses data of {@link CoreMetrics#DUPLICATIONS_DATA}.
*/
private static List<List<Block>> parseDuplicationData(String data) {
+ ImmutableList.Builder<List<Block>> groups = ImmutableList.builder();
try {
- ImmutableList.Builder<List<Block>> groups = ImmutableList.builder();
StringReader reader = new StringReader(data);
SMInputFactory inputFactory = initStax();
SMHierarchicCursor rootC = inputFactory.rootElementCursor(reader);
}
groups.add(group.build());
}
- return groups.build();
- } catch (XMLStreamException e) {
- throw new SonarException(e.getMessage(), e);
+ } catch (Exception e) {
+ // SONAR-6174 Ignore any issue while parsing duplication measure. There is nothing user can do and things will get solved after
+ // next analysis anyway
}
+ return groups.build();
}
private static int getAttrIntValue(SMInputCursor cursor, String attrName) throws XMLStreamException {
import org.junit.Before;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
+import org.junit.rules.ExpectedException;
import org.sonar.core.persistence.AbstractDaoTestCase;
import org.sonar.core.persistence.BatchSession;
import org.sonar.core.persistence.DbTester;
+import org.sonar.server.db.migrations.Select.Row;
+import org.sonar.server.db.migrations.Select.RowReader;
import org.sonar.test.DbTests;
import java.sql.SQLException;
@ClassRule
public static DbTester db = new DbTester().schema(BaseDataChangeTest.class, "schema.sql");
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
@Before
public void setUp() throws Exception {
db.executeUpdateSql("truncate table persons");
assertThat(ids).containsOnly(2L, 3L);
}
+ @Test
+ public void display_current_row_details_if_error_during_get() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=2]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).get(new RowReader<Long>() {
+ @Override
+ public Long read(Row row) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ }
+ }.execute();
+
+ }
+
+ @Test
+ public void display_current_row_details_if_error_during_list() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=2]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ context.prepareSelect("select id from persons where id>=?").setLong(1, 2L).list(new RowReader<Long>() {
+ @Override
+ public Long read(Row row) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ }
+ }.execute();
+
+ }
+
@Test
public void bad_parameterized_query() throws Exception {
db.prepareDbUnit(getClass(), "persons.xml");
ids.addAll(context.prepareSelect("select id from persons where id>=?").list(Select.LONG_READER));
}
};
- try {
- change.execute();
- fail();
- } catch (SQLException e) {
- // ok
- }
+
+ thrown.expect(SQLException.class);
+
+ change.execute();
}
@Test
db.assertDbUnit(getClass(), "scroll-and-update-result.xml", "persons");
}
+ @Test
+ public void display_current_row_details_if_error_during_scroll() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=1]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ final Upsert upsert = context.prepareUpsert("update persons set login=?, age=? where id=?");
+ context.prepareSelect("select id from persons").scroll(new Select.RowHandler() {
+ @Override
+ public void handle(Select.Row row) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ upsert.commit().close();
+ }
+ }.execute();
+ }
+
@Test
public void mass_update() throws Exception {
db.prepareDbUnit(getClass(), "persons.xml");
db.assertDbUnit(getClass(), "mass-update-result.xml", "persons");
}
+ @Test
+ public void display_current_row_details_if_error_during_mass_update() throws Exception {
+ db.prepareDbUnit(getClass(), "persons.xml");
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=2]");
+
+ new BaseDataChange(db.database()) {
+ @Override
+ public void execute(Context context) throws SQLException {
+ MassUpdate massUpdate = context.prepareMassUpdate();
+ massUpdate.select("select id from persons where id>=?").setLong(1, 2L);
+ massUpdate.update("update persons set login=?, age=? where id=?");
+ massUpdate.execute(new MassUpdate.Handler() {
+ @Override
+ public boolean handle(Select.Row row, SqlStatement update) throws SQLException {
+ throw new IllegalStateException("Unexpected error");
+ }
+ });
+ }
+ }.execute();
+ }
+
@Test
public void mass_update_nothing() throws Exception {
db.prepareDbUnit(getClass(), "persons.xml");
db.assertDbUnit(getClass(), "after-with-scm.xml", "file_sources");
}
+
+ @Test
+ public void migrate_sources_with_invalid_duplication() throws Exception {
+ db.prepareDbUnit(getClass(), "before.xml");
+
+ Connection connection = null;
+ try {
+ connection = db.openConnection();
+
+ connection.prepareStatement("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(6, 'class Foo {\r\n // Empty\r\n}\r\n', '2014-10-31 16:44:02.000')")
+ .executeUpdate();
+
+ db.executeUpdateSql("insert into snapshot_sources " +
+ "(snapshot_id, data, updated_at) " +
+ "values " +
+ "(7, '', '2014-10-31 16:44:02.000')");
+
+ PreparedStatement duplicationDataStmt = connection.prepareStatement("insert into project_measures " +
+ "(metric_id, snapshot_id, text_value) " +
+ "values " +
+ "(13, 6, ?)");
+ duplicationDataStmt
+ .setBytes(
+ 1,
+ "<duplications><g><b s=\"1\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"2\" l=\"1\" r=\"MyProject:src/main/xoo/prj/MyFile.xoo\"/><b s=\"3\" l=\"1\" r=\"MyProject:src/main/xoo/prj/AnotherFile.xoo\"/"
+ .getBytes(Charsets.UTF_8));
+ duplicationDataStmt.executeUpdate();
+ } finally {
+ DbUtils.commitAndCloseQuietly(connection);
+ }
+
+ migration.execute();
+
+ db.assertDbUnit(getClass(), "after-with-invalid-duplication.xml", "file_sources");
+ }
}
import org.apache.commons.dbutils.DbUtils;
import org.junit.ClassRule;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.ExpectedException;
import org.sonar.core.persistence.DbTester;
import org.sonar.core.source.db.FileSourceDto;
import org.sonar.server.db.migrations.DatabaseMigration;
import java.sql.SQLException;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.Assert.fail;
public class FeedFileSourcesBinaryDataTest {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
@ClassRule
public static DbTester db = new DbTester().schema(FeedFileSourcesBinaryDataTest.class, "schema.sql");
int count = db.countSql("select count(*) from file_sources where binary_data is not null");
assertThat(count).isEqualTo(3);
- try(Connection connection = db.openConnection()) {
+ try (Connection connection = db.openConnection()) {
FileSourceDb.Data data = selectData(connection, 1L);
assertThat(data.getLinesCount()).isEqualTo(4);
assertThat(data.getLines(0).getScmRevision()).isEqualTo("aef12a");
db.prepareDbUnit(getClass(), "bad_data.xml");
DatabaseMigration migration = new FeedFileSourcesBinaryData(db.database());
- try {
- migration.execute();
- fail();
- } catch (IllegalStateException e) {
- assertThat(e).hasMessageContaining("Invalid FILE_SOURCES.DATA on row with ID 1:");
- }
+
+ thrown.expect(IllegalStateException.class);
+ thrown.expectMessage("Error during processing of row: [id=1]");
+
+ migration.execute();
}
private FileSourceDb.Data selectData(Connection connection, long fileSourceId) throws SQLException {
--- /dev/null
+<dataset>
+
+ <file_sources id="1" project_uuid="uuid-MyProject" file_uuid="uuid-Migrated.xoo" created_at="1416238020000" updated_at="1414770242000"
+ data=""
+ line_hashes=""
+ data_hash="" />
+
+ <file_sources id="2" project_uuid="uuid-MyProject" file_uuid="uuid-MyFile.xoo" created_at="1416238020000" updated_at="1414770242000"
+ data=",,,,,,,,,,,,,,,class Foo { ,,,,,,,,,,,,,,, // Empty ,,,,,,,,,,,,,,,} ,,,,,,,,,,,,,,, "
+ line_hashes="6a19ce786467960a3a9b0d26383a464a aab2dbc5fdeaa80b050b1d049ede357c cbb184dd8e05c9709e5dcaedaa0495cf "
+ data_hash="" />
+
+</dataset>