Skip to content

Commit cf393fc

Browse files
committed
CSVParser.iterator() knows how to use CSVFormat's maxRows
1 parent 9b75f05 commit cf393fc

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
<action type="add" dev="ggregory" due-to="Gary Gregory">CSVPrinter.printRecords(Stream) knows how to use CSVFormat's maxRows.</action>
5454
<action type="add" dev="ggregory" due-to="Gary Gregory">CSVParser.stream() knows how to use CSVFormat's maxRows.</action>
5555
<action type="add" dev="ggregory" due-to="Gary Gregory">CSVParser.getRecords() knows how to use CSVFormat's maxRows.</action>
56+
<action type="add" dev="ggregory" due-to="Gary Gregory">CSVParser.iterator() knows how to use CSVFormat's maxRows.</action>
5657
<!-- UPDATE -->
5758
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump com.opencsv:opencsv from 5.9 to 5.10.</action>
5859
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump commons-codec:commons-codec from 1.17.2 to 1.18.0 #522.</action>

src/main/java/org/apache/commons/csv/CSVFormat.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2091,11 +2091,11 @@ public boolean isQuoteCharacterSet() {
20912091
}
20922092

20932093
<T> IOStream<T> limit(final IOStream<T> stream) {
2094-
return getMaxRows() > 0 ? stream.limit(getMaxRows()) : stream;
2094+
return useMaxRows() ? stream.limit(getMaxRows()) : stream;
20952095
}
20962096

20972097
<T> Stream<T> limit(final Stream<T> stream) {
2098-
return getMaxRows() > 0 ? stream.limit(getMaxRows()) : stream;
2098+
return useMaxRows() ? stream.limit(getMaxRows()) : stream;
20992099
}
21002100

21012101
/**
@@ -2582,6 +2582,14 @@ String trim(final String value) {
25822582
return getTrim() ? value.trim() : value;
25832583
}
25842584

2585+
boolean useMaxRows() {
2586+
return getMaxRows() > 0;
2587+
}
2588+
2589+
boolean useRow(final long rowNum) {
2590+
return !useMaxRows() || rowNum <= getMaxRows();
2591+
}
2592+
25852593
/**
25862594
* Verifies the validity and consistency of the attributes, and throws an {@link IllegalArgumentException} if necessary.
25872595
* <p>

src/main/java/org/apache/commons/csv/CSVParser.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,18 @@ final class CSVRecordIterator implements Iterator<CSVRecord> {
221221
private CSVRecord current;
222222

223223
/**
224-
* Gets the next record.
224+
* Gets the next record or null at the end of stream or max rows read.
225225
*
226226
* @throws IOException on parse error or input read-failure
227227
* @throws CSVException on invalid input.
228228
* @return the next record, or {@code null} if the end of the stream has been reached.
229229
*/
230230
private CSVRecord getNextRecord() {
231-
return Uncheck.get(CSVParser.this::nextRecord);
231+
CSVRecord record = null;
232+
if (format.useRow(recordNumber + 1)) {
233+
record = Uncheck.get(CSVParser.this::nextRecord);
234+
}
235+
return record;
232236
}
233237

234238
@Override
@@ -938,7 +942,7 @@ CSVRecord nextRecord() throws IOException {
938942
* @since 1.9.0
939943
*/
940944
public Stream<CSVRecord> stream() {
941-
return format.limit(StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator(), Spliterator.ORDERED), false));
945+
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator(), Spliterator.ORDERED), false);
942946
}
943947

944948
}

src/main/java/org/apache/commons/csv/CSVPrinter.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -445,8 +445,7 @@ public void printRecords(final Object... values) throws IOException {
445445
*/
446446
public void printRecords(final ResultSet resultSet) throws SQLException, IOException {
447447
final int columnCount = resultSet.getMetaData().getColumnCount();
448-
final long maxRows = format.getMaxRows();
449-
while (resultSet.next() && (maxRows < 1 || resultSet.getRow() <= maxRows)) {
448+
while (resultSet.next() && format.useRow(resultSet.getRow())) {
450449
for (int i = 1; i <= columnCount; i++) {
451450
final Object object = resultSet.getObject(i);
452451
if (object instanceof Clob) {

src/test/java/org/apache/commons/csv/CSVParserTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,34 @@ public void testIterator() throws Exception {
11641164
}
11651165
}
11661166

1167+
@ParameterizedTest
1168+
@ValueSource(longs = { -1, 0, 1, 2, 3, 4, 5, Long.MAX_VALUE })
1169+
public void testIteratorMaxRows(final long maxRows) throws Exception {
1170+
final Reader in = new StringReader("a,b,c\n1,2,3\nx,y,z");
1171+
try (CSVParser parser = CSVFormat.DEFAULT.builder().setMaxRows(maxRows).get().parse(in)) {
1172+
final Iterator<CSVRecord> iterator = parser.iterator();
1173+
assertTrue(iterator.hasNext());
1174+
assertThrows(UnsupportedOperationException.class, iterator::remove);
1175+
assertArrayEquals(new String[] { "a", "b", "c" }, iterator.next().values());
1176+
final boolean noLimit = maxRows <= 0;
1177+
final int fixtureLen = 3;
1178+
final long expectedLen = noLimit ? fixtureLen : Math.min(fixtureLen, maxRows);
1179+
if (expectedLen > 1) {
1180+
assertTrue(iterator.hasNext());
1181+
assertArrayEquals(new String[] { "1", "2", "3" }, iterator.next().values());
1182+
}
1183+
assertEquals(expectedLen > 2, iterator.hasNext());
1184+
// again
1185+
assertEquals(expectedLen > 2, iterator.hasNext());
1186+
if (expectedLen == fixtureLen) {
1187+
assertTrue(iterator.hasNext());
1188+
assertArrayEquals(new String[] { "x", "y", "z" }, iterator.next().values());
1189+
}
1190+
assertFalse(iterator.hasNext());
1191+
assertThrows(NoSuchElementException.class, iterator::next);
1192+
}
1193+
}
1194+
11671195
@Test
11681196
public void testIteratorSequenceBreaking() throws IOException {
11691197
final String fiveRows = "1\n2\n3\n4\n5\n";

0 commit comments

Comments
 (0)