Skip to content

Commit 30f0e1d

Browse files
committed
CSVPrinter.printRecords(ResultSet) knows how to use CSVFormat's maxRows
- Add CSVFormat.Builder.setMaxRows(long) - Add CSVFormat.getMaxRows()
1 parent c62d12a commit 30f0e1d

File tree

4 files changed

+148
-95
lines changed

4 files changed

+148
-95
lines changed

src/changes/changes.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
<action type="fix" dev="ggregory" due-to="Gary Gregory">Remove -nouses directive from maven-bundle-plugin. OSGi package imports now state 'uses' definitions for package imports, this doesn't affect JPMS (from org.apache.commons:commons-parent:80).</action>
4747
<!-- ADD -->
4848
<action type="add" dev="ggregory" due-to="Gary Gregory">Define and use Maven property commons.jmh.version.</action>
49+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add CSVFormat.Builder.setMaxRows(long).</action>
50+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add CSVFormat.getMaxRows().</action>
51+
<action type="add" dev="ggregory" due-to="Gary Gregory">CSVPrinter.printRecords(ResultSet) knows how to use CSVFormat's maxRows.</action>
4952
<!-- UPDATE -->
5053
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump com.opencsv:opencsv from 5.9 to 5.10.</action>
5154
<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: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -270,32 +270,36 @@ public static Builder create(final CSVFormat csvFormat) {
270270

271271
private boolean trim;
272272

273+
/** The maximum number of rows to process, excluding the header row. */
274+
private long maxRows;
275+
273276
private Builder() {
274277
// empty
275278
}
276279

277280
private Builder(final CSVFormat csvFormat) {
278-
this.delimiter = csvFormat.delimiter;
279-
this.quoteCharacter = csvFormat.quoteCharacter;
280-
this.quoteMode = csvFormat.quoteMode;
281+
this.allowMissingColumnNames = csvFormat.allowMissingColumnNames;
282+
this.autoFlush = csvFormat.autoFlush;
281283
this.commentMarker = csvFormat.commentMarker;
284+
this.delimiter = csvFormat.delimiter;
285+
this.duplicateHeaderMode = csvFormat.duplicateHeaderMode;
282286
this.escapeCharacter = csvFormat.escapeCharacter;
283-
this.ignoreSurroundingSpaces = csvFormat.ignoreSurroundingSpaces;
284-
this.allowMissingColumnNames = csvFormat.allowMissingColumnNames;
285-
this.ignoreEmptyLines = csvFormat.ignoreEmptyLines;
286-
this.recordSeparator = csvFormat.recordSeparator;
287-
this.nullString = csvFormat.nullString;
288287
this.headerComments = csvFormat.headerComments;
289288
this.headers = csvFormat.headers;
290-
this.skipHeaderRecord = csvFormat.skipHeaderRecord;
289+
this.ignoreEmptyLines = csvFormat.ignoreEmptyLines;
291290
this.ignoreHeaderCase = csvFormat.ignoreHeaderCase;
291+
this.ignoreSurroundingSpaces = csvFormat.ignoreSurroundingSpaces;
292292
this.lenientEof = csvFormat.lenientEof;
293+
this.maxRows = csvFormat.maxRows;
294+
this.nullString = csvFormat.nullString;
295+
this.quoteCharacter = csvFormat.quoteCharacter;
296+
this.quoteMode = csvFormat.quoteMode;
297+
this.quotedNullString = csvFormat.quotedNullString;
298+
this.recordSeparator = csvFormat.recordSeparator;
299+
this.skipHeaderRecord = csvFormat.skipHeaderRecord;
293300
this.trailingData = csvFormat.trailingData;
294301
this.trailingDelimiter = csvFormat.trailingDelimiter;
295302
this.trim = csvFormat.trim;
296-
this.autoFlush = csvFormat.autoFlush;
297-
this.quotedNullString = csvFormat.quotedNullString;
298-
this.duplicateHeaderMode = csvFormat.duplicateHeaderMode;
299303
}
300304

301305
/**
@@ -738,6 +742,18 @@ public Builder setLenientEof(final boolean lenientEof) {
738742
return this;
739743
}
740744

745+
/**
746+
* Sets the maximum number of rows to process, excluding the header row.
747+
*
748+
* @param maxRows the maximum number of rows to process, excluding the header row.
749+
* @return This instance.
750+
* @since 1.14.0
751+
*/
752+
public Builder setMaxRows(final long maxRows) {
753+
this.maxRows = maxRows;
754+
return this;
755+
}
756+
741757
/**
742758
* Sets the String to convert to and from {@code null}. No substitution occurs if {@code null}.
743759
*
@@ -857,6 +873,7 @@ public Builder setTrailingDelimiter(final boolean trailingDelimiter) {
857873
return this;
858874
}
859875

876+
860877
/**
861878
* Sets whether to trim leading and trailing blanks.
862879
*
@@ -1580,28 +1597,32 @@ public static CSVFormat valueOf(final String format) {
15801597
/** Whether to trim leading and trailing blanks. */
15811598
private final boolean trim;
15821599

1600+
/** The maximum number of rows to process, excluding the header row. */
1601+
private final long maxRows;
1602+
15831603
private CSVFormat(final Builder builder) {
1584-
this.delimiter = builder.delimiter;
1585-
this.quoteCharacter = builder.quoteCharacter;
1586-
this.quoteMode = builder.quoteMode;
1604+
this.allowMissingColumnNames = builder.allowMissingColumnNames;
1605+
this.autoFlush = builder.autoFlush;
15871606
this.commentMarker = builder.commentMarker;
1607+
this.delimiter = builder.delimiter;
1608+
this.duplicateHeaderMode = builder.duplicateHeaderMode;
15881609
this.escapeCharacter = builder.escapeCharacter;
1589-
this.ignoreSurroundingSpaces = builder.ignoreSurroundingSpaces;
1590-
this.allowMissingColumnNames = builder.allowMissingColumnNames;
1591-
this.ignoreEmptyLines = builder.ignoreEmptyLines;
1592-
this.recordSeparator = builder.recordSeparator;
1593-
this.nullString = builder.nullString;
15941610
this.headerComments = builder.headerComments;
15951611
this.headers = builder.headers;
1596-
this.skipHeaderRecord = builder.skipHeaderRecord;
1612+
this.ignoreEmptyLines = builder.ignoreEmptyLines;
15971613
this.ignoreHeaderCase = builder.ignoreHeaderCase;
1614+
this.ignoreSurroundingSpaces = builder.ignoreSurroundingSpaces;
15981615
this.lenientEof = builder.lenientEof;
1616+
this.maxRows = builder.maxRows;
1617+
this.nullString = builder.nullString;
1618+
this.quoteCharacter = builder.quoteCharacter;
1619+
this.quoteMode = builder.quoteMode;
1620+
this.quotedNullString = builder.quotedNullString;
1621+
this.recordSeparator = builder.recordSeparator;
1622+
this.skipHeaderRecord = builder.skipHeaderRecord;
15991623
this.trailingData = builder.trailingData;
16001624
this.trailingDelimiter = builder.trailingDelimiter;
16011625
this.trim = builder.trim;
1602-
this.autoFlush = builder.autoFlush;
1603-
this.quotedNullString = builder.quotedNullString;
1604-
this.duplicateHeaderMode = builder.duplicateHeaderMode;
16051626
validate();
16061627
}
16071628

@@ -1898,6 +1919,16 @@ public boolean getLenientEof() {
18981919
return lenientEof;
18991920
}
19001921

1922+
/**
1923+
* Gets the maximum number of rows to process, excluding the header row.
1924+
*
1925+
* @return The maximum number of rows to process, excluding the header row.
1926+
* @since 1.14.0
1927+
*/
1928+
public long getMaxRows() {
1929+
return maxRows;
1930+
}
1931+
19011932
/**
19021933
* Gets the String to convert to and from {@code null}.
19031934
* <ul>
@@ -1982,10 +2013,9 @@ public int hashCode() {
19822013
int result = 1;
19832014
result = prime * result + Arrays.hashCode(headerComments);
19842015
result = prime * result + Arrays.hashCode(headers);
1985-
result = prime * result + Objects.hash(allowMissingColumnNames, autoFlush, commentMarker, delimiter, duplicateHeaderMode, escapeCharacter,
2016+
return prime * result + Objects.hash(allowMissingColumnNames, autoFlush, commentMarker, delimiter, duplicateHeaderMode, escapeCharacter,
19862017
ignoreEmptyLines, ignoreHeaderCase, ignoreSurroundingSpaces, lenientEof, nullString, quoteCharacter, quoteMode, quotedNullString,
19872018
recordSeparator, skipHeaderRecord, trailingData, trailingDelimiter, trim);
1988-
return result;
19892019
}
19902020

19912021
/**

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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.sql.Clob;
3333
import java.sql.ResultSet;
3434
import java.sql.SQLException;
35+
import java.sql.Statement;
3536
import java.util.Arrays;
3637
import java.util.Objects;
3738
import java.util.stream.Stream;
@@ -428,17 +429,19 @@ public void printRecords(final Object... values) throws IOException {
428429

429430
/**
430431
* Prints all the objects in the given JDBC result set.
432+
* <p>
433+
* You can use {@link CSVFormat.Builder#setMaxRows(long)} to limit how many rows a result set produces. This is most useful when you cannot limit rows
434+
* through {@link Statement#setLargeMaxRows(long)}.
435+
* </p>
431436
*
432-
* @param resultSet
433-
* The values to print.
434-
* @throws IOException
435-
* If an I/O error occurs.
436-
* @throws SQLException
437-
* Thrown when a database access error occurs.
437+
* @param resultSet The values to print.
438+
* @throws IOException If an I/O error occurs.
439+
* @throws SQLException Thrown when a database access error occurs.
438440
*/
439441
public void printRecords(final ResultSet resultSet) throws SQLException, IOException {
440442
final int columnCount = resultSet.getMetaData().getColumnCount();
441-
while (resultSet.next()) {
443+
final long maxRows = format.getMaxRows();
444+
while (resultSet.next() && (maxRows < 1 || resultSet.getRow() <= maxRows)) {
442445
for (int i = 1; i <= columnCount; i++) {
443446
final Object object = resultSet.getObject(i);
444447
if (object instanceof Clob) {
@@ -459,6 +462,10 @@ public void printRecords(final ResultSet resultSet) throws SQLException, IOExcep
459462

460463
/**
461464
* Prints all the objects with metadata in the given JDBC result set based on the header boolean.
465+
* <p>
466+
* You can use {@link CSVFormat.Builder#setMaxRows(long)} to limit how many rows a result set produces. This is most useful when you cannot limit rows
467+
* through {@link Statement#setLargeMaxRows(long)}.
468+
* </p>
462469
*
463470
* @param resultSet source of row data.
464471
* @param printHeader whether to print headers.

0 commit comments

Comments
 (0)