/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program 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. * * This program 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. */ package org.sonar.db; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.NoSuchElementException; import org.junit.Rule; import org.junit.Test; import org.sonar.api.utils.System2; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; public class ResultSetIteratorTest { @Rule public CoreDbTester dbTester = CoreDbTester.createForSchema(ResultSetIteratorTest.class, "schema.sql"); @Test public void create_iterator_from_statement() throws Exception { dbTester.prepareDbUnit(getClass(), "feed.xml"); try (Connection connection = dbTester.openConnection()) { PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); FirstIntColumnIterator iterator = new FirstIntColumnIterator(stmt); assertThat(iterator.hasNext()).isTrue(); // calling multiple times hasNext() is ok assertThat(iterator.hasNext()).isTrue(); assertThat(iterator.next()).isEqualTo(10); assertThat(iterator.hasNext()).isTrue(); assertThat(iterator.next()).isEqualTo(20); // call next() without calling hasNext() assertThat(iterator.next()).isEqualTo(30); assertThat(iterator.hasNext()).isFalse(); try { iterator.next(); fail(); } catch (NoSuchElementException e) { // ok } iterator.close(); // statement is closed by ResultSetIterator assertThat(stmt.isClosed()).isTrue(); } } @Test public void iterate_empty_list() throws Exception { dbTester.prepareDbUnit(getClass(), "feed.xml"); try (Connection connection = dbTester.openConnection()) { PreparedStatement stmt = connection.prepareStatement("select * from issues where id < 0"); FirstIntColumnIterator iterator = new FirstIntColumnIterator(stmt); assertThat(iterator.hasNext()).isFalse(); } } @Test public void create_iterator_from_result_set() throws Exception { dbTester.prepareDbUnit(getClass(), "feed.xml"); try (Connection connection = dbTester.openConnection()) { PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); ResultSet rs = stmt.executeQuery(); FirstIntColumnIterator iterator = new FirstIntColumnIterator(rs); assertThat(iterator.next()).isEqualTo(10); assertThat(iterator.next()).isEqualTo(20); assertThat(iterator.next()).isEqualTo(30); iterator.close(); assertThat(rs.isClosed()).isTrue(); stmt.close(); } } @Test public void remove_row_is_not_supported() throws Exception { try (Connection connection = dbTester.openConnection()) { PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); FirstIntColumnIterator iterator = new FirstIntColumnIterator(stmt); try { iterator.remove(); fail(); } catch (UnsupportedOperationException ok) { // ok } iterator.close(); } } @Test public void fail_to_read_row() throws Exception { dbTester.prepareDbUnit(getClass(), "feed.xml"); try (Connection connection = dbTester.openConnection()) { PreparedStatement stmt = connection.prepareStatement("select * from issues order by id"); FailIterator iterator = new FailIterator(stmt); assertThat(iterator.hasNext()).isTrue(); try { iterator.next(); fail(); } catch (IllegalStateException e) { assertThat(e.getCause()).isInstanceOf(SQLException.class); } iterator.close(); } } private static class FirstIntColumnIterator extends ResultSetIterator<Integer> { public FirstIntColumnIterator(PreparedStatement stmt) throws SQLException { super(stmt); } public FirstIntColumnIterator(ResultSet rs) { super(rs); } @Override protected Integer read(ResultSet rs) throws SQLException { return rs.getInt(1); } } private static class FailIterator extends ResultSetIterator<Integer> { public FailIterator(PreparedStatement stmt) throws SQLException { super(stmt); } @Override protected Integer read(ResultSet rs) throws SQLException { // column does not exist return rs.getInt(1234); } } }