[#4451] Add DSLContext.fetchFromCSV(boolean) to allow for fetching header-less CSV data

This commit is contained in:
lukaseder 2015-08-03 11:24:06 +02:00
parent 58a4e74d28
commit bc3fabc4e1
2 changed files with 124 additions and 19 deletions

View File

@ -2176,12 +2176,12 @@ public interface DSLContext extends Scope {
* conversion methods to retrieve other data types from the
* <code>Result</code>:
* <ul>
* <li> {@link Result#getValues(Field, Class)}</li>
* <li> {@link Result#getValues(int, Class)}</li>
* <li> {@link Result#getValues(String, Class)}</li>
* <li> {@link Result#getValues(Field, Converter)}</li>
* <li> {@link Result#getValues(int, Converter)}</li>
* <li> {@link Result#getValues(String, Converter)}</li>
* <li>{@link Result#getValues(Field, Class)}</li>
* <li>{@link Result#getValues(int, Class)}</li>
* <li>{@link Result#getValues(String, Class)}</li>
* <li>{@link Result#getValues(Field, Converter)}</li>
* <li>{@link Result#getValues(int, Converter)}</li>
* <li>{@link Result#getValues(String, Converter)}</li>
* </ul>
* <p>
* Missing values result in <code>null</code>. Empty values result in empty
@ -2204,12 +2204,12 @@ public interface DSLContext extends Scope {
* various conversion methods to retrieve other data types from the
* <code>Result</code>:
* <ul>
* <li> {@link Result#getValues(Field, Class)}</li>
* <li> {@link Result#getValues(int, Class)}</li>
* <li> {@link Result#getValues(String, Class)}</li>
* <li> {@link Result#getValues(Field, Converter)}</li>
* <li> {@link Result#getValues(int, Converter)}</li>
* <li> {@link Result#getValues(String, Converter)}</li>
* <li>{@link Result#getValues(Field, Class)}</li>
* <li>{@link Result#getValues(int, Class)}</li>
* <li>{@link Result#getValues(String, Class)}</li>
* <li>{@link Result#getValues(Field, Converter)}</li>
* <li>{@link Result#getValues(int, Converter)}</li>
* <li>{@link Result#getValues(String, Converter)}</li>
* </ul>
* <p>
* Missing values result in <code>null</code>. Empty values result in empty
@ -2225,6 +2225,65 @@ public interface DSLContext extends Scope {
@Support
Result<Record> fetchFromCSV(String string, char delimiter) throws DataAccessException;
/**
* Fetch all data from a CSV string.
* <p>
* This is the same as calling <code>fetchFromCSV(string, ',')</code> and
* the inverse of calling {@link Result#formatCSV(boolean)}. Rows may
* contain data, which is interpreted as {@link String}. Use the various
* conversion methods to retrieve other data types from the
* <code>Result</code>:
* <ul>
* <li>{@link Result#getValues(Field, Class)}</li>
* <li>{@link Result#getValues(int, Class)}</li>
* <li>{@link Result#getValues(String, Class)}</li>
* <li>{@link Result#getValues(Field, Converter)}</li>
* <li>{@link Result#getValues(int, Converter)}</li>
* <li>{@link Result#getValues(String, Converter)}</li>
* </ul>
* <p>
* Missing values result in <code>null</code>. Empty values result in empty
* <code>Strings</code>
*
* @param string The CSV string
* @param header Whether to parse the first line as a CSV header line
* @return The transformed result
* @throws DataAccessException If anything went wrong parsing the CSV file
* @see #fetchFromCSV(String, char)
*/
@Support
Result<Record> fetchFromCSV(String string, boolean header) throws DataAccessException;
/**
* Fetch all data from a CSV string.
* <p>
* This is inverse of calling {@link Result#formatCSV(boolean, char)}. Rows
* may contain data, which are interpreted as {@link String}. Use the
* various conversion methods to retrieve other data types from the
* <code>Result</code>:
* <ul>
* <li>{@link Result#getValues(Field, Class)}</li>
* <li>{@link Result#getValues(int, Class)}</li>
* <li>{@link Result#getValues(String, Class)}</li>
* <li>{@link Result#getValues(Field, Converter)}</li>
* <li>{@link Result#getValues(int, Converter)}</li>
* <li>{@link Result#getValues(String, Converter)}</li>
* </ul>
* <p>
* Missing values result in <code>null</code>. Empty values result in empty
* <code>Strings</code>
*
* @param string The CSV string
* @param header Whether to parse the first line as a CSV header line
* @param delimiter The delimiter to expect between records
* @return The transformed result
* @throws DataAccessException If anything went wrong parsing the CSV file
* @see #fetchFromCSV(String)
* @see #fetchFromStringData(List)
*/
@Support
Result<Record> fetchFromCSV(String string, boolean header, char delimiter) throws DataAccessException;
/**
* Fetch all data from a JSON string.
* <p>
@ -2289,6 +2348,25 @@ public interface DSLContext extends Scope {
*/
Result<Record> fetchFromStringData(List<String[]> data);
/**
* Fetch all data from a list of strings.
* <p>
* This is used by methods such as
* <ul>
* <li>{@link #fetchFromCSV(String)}</li>
* <li>{@link #fetchFromTXT(String)}</li>
* </ul>
* The degree of all arrays contained in the argument should be the same,
* although this is not a requirement. jOOQ will ignore excess data, and
* fill missing data with <code>null</code>.
*
* @param data The data to be transformed into a <code>Result</code>
* @param header Whether to interpret the first line as a set of column
* names.
* @return The transformed result
*/
Result<Record> fetchFromStringData(List<String[]> data, boolean header);
// -------------------------------------------------------------------------
// XXX Global Query factory
// -------------------------------------------------------------------------

View File

@ -863,11 +863,21 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
@Override
public Result<Record> fetchFromCSV(String string) {
return fetchFromCSV(string, ',');
return fetchFromCSV(string, true, ',');
}
@Override
public Result<Record> fetchFromCSV(String string, char delimiter) {
return fetchFromCSV(string, true, delimiter);
}
@Override
public Result<Record> fetchFromCSV(String string, boolean header) {
return fetchFromCSV(string, header, ',');
}
@Override
public Result<Record> fetchFromCSV(String string, boolean header, char delimiter) {
CSVReader reader = new CSVReader(new StringReader(string), delimiter);
List<String[]> list = null;
@ -884,7 +894,7 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
catch (IOException ignore) {}
}
return fetchFromStringData(list);
return fetchFromStringData(header, list);
}
@Override
@ -915,25 +925,42 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
@Override
public Result<Record> fetchFromStringData(String[]... strings) {
return fetchFromStringData(list(strings));
return fetchFromStringData(list(strings), true);
}
@Override
public Result<Record> fetchFromStringData(List<String[]> strings) {
return fetchFromStringData(strings, true);
}
@Override
public Result<Record> fetchFromStringData(List<String[]> strings, boolean header) {
if (strings.size() == 0) {
return new ResultImpl<Record>(configuration());
}
else {
List<Field<?>> fields = new ArrayList<Field<?>>();
int firstRow;
for (String name : strings.get(0)) {
fields.add(field(name(name), String.class));
if (header) {
firstRow = 1;
for (String name : strings.get(0)) {
fields.add(field(name(name), String.class));
}
}
else {
firstRow = 0;
for (int i = 0; i < strings.get(0).length; i++) {
fields.add(field(name("COL" + (i + 1)), String.class));
}
}
Result<Record> result = new ResultImpl<Record>(configuration(), fields);
if (strings.size() > 1) {
for (String[] values : strings.subList(1, strings.size())) {
if (strings.size() > firstRow) {
for (String[] values : strings.subList(firstRow, strings.size())) {
RecordImpl record = new RecordImpl(fields);
for (int i = 0; i < Math.min(values.length, fields.size()); i++) {