提交 1db17c7a authored 作者: Thomas Mueller's avatar Thomas Mueller

CSVREAD: when reading the column names from the CSV file, column names that…

CSVREAD: when reading the column names from the CSV file, column names that contain no special characters are considered case insensitive now.
上级 faefbd48
...@@ -3168,10 +3168,12 @@ Returns the result set of reading the CSV (comma separated values) file. ...@@ -3168,10 +3168,12 @@ Returns the result set of reading the CSV (comma separated values) file.
For each parameter, NULL means the default value should be used. For each parameter, NULL means the default value should be used.
If the column names are specified (a list of column names separated with the If the column names are specified (a list of column names separated with the
fieldSeparator), those are used they are read from the file, otherwise fieldSeparator), those are used, otherwise (or if they are set to NULL) the first line of
(or if they are set to NULL) the first line of the file is interpreted as the column names. the file is interpreted as the column names.
Column names are case sensitive, that means you need to use quoted identifiers In that case, column names that contain no special characters (only letters, '_',
unless the column names are capitalized (see below). and digits; similar to the rule for Java identifiers) are considered case insensitive.
Other column names are case sensitive, that means you need to use quoted identifiers
(see below).
The default charset is the default value for this system, and the default field separator The default charset is the default value for this system, and the default field separator
is a comma. Missing unquoted values as well as data that matches nullString is is a comma. Missing unquoted values as well as data that matches nullString is
......
...@@ -159,9 +159,16 @@ public class Csv implements SimpleRowSource { ...@@ -159,9 +159,16 @@ public class Csv implements SimpleRowSource {
* Reads from the CSV file and returns a result set. The rows in the result * Reads from the CSV file and returns a result set. The rows in the result
* set are created on demand, that means the file is kept open until all * set are created on demand, that means the file is kept open until all
* rows are read or the result set is closed. * rows are read or the result set is closed.
* <br />
* If the columns are read from the CSV file, then the following rules are
* used: columns names that start with a letter or '_', and only
* contain letters, '_', and digits, are considered case insensitive
* and are converted to uppercase. Other column names are considered
* case sensitive (that means they need to be quoted when accessed).
* *
* @param inputFileName the file name * @param inputFileName the file name
* @param colNames or null if the column names should be read from the CSV file * @param colNames or null if the column names should be read from the CSV
* file
* @param charset the charset or null to use UTF-8 * @param charset the charset or null to use UTF-8
* @return the result set * @return the result set
* @throws SQLException * @throws SQLException
...@@ -313,9 +320,15 @@ public class Csv implements SimpleRowSource { ...@@ -313,9 +320,15 @@ public class Csv implements SimpleRowSource {
break; break;
} }
} else { } else {
list.add("COLUMN" + list.size()); v = "COLUMN" + list.size();
list.add(v);
} }
} else { } else {
if (v.length() == 0) {
v = "COLUMN" + list.size();
} else if (isSimpleColumnName(v)) {
v = v.toUpperCase();
}
list.add(v); list.add(v);
if (endOfLine) { if (endOfLine) {
break; break;
...@@ -326,6 +339,25 @@ public class Csv implements SimpleRowSource { ...@@ -326,6 +339,25 @@ public class Csv implements SimpleRowSource {
list.toArray(columnNames); list.toArray(columnNames);
} }
private boolean isSimpleColumnName(String columnName) {
for (int i = 0; i < columnName.length(); i++) {
char ch = columnName.charAt(i);
if (i == 0) {
if (ch != '_' && !Character.isLetter(ch)) {
return false;
}
} else {
if (ch != '_' && !Character.isLetterOrDigit(ch)) {
return false;
}
}
}
if (columnName.length() == 0) {
return false;
}
return true;
}
private void pushBack() { private void pushBack() {
inputBufferPos--; inputBufferPos--;
} }
......
...@@ -8,6 +8,7 @@ package org.h2.test.db; ...@@ -8,6 +8,7 @@ package org.h2.test.db;
import java.io.File; import java.io.File;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.StringReader;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -16,7 +17,6 @@ import java.sql.SQLException; ...@@ -16,7 +17,6 @@ import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
import org.h2.store.fs.FileObject; import org.h2.store.fs.FileObject;
import org.h2.store.fs.FileSystem; import org.h2.store.fs.FileSystem;
import org.h2.test.TestBase; import org.h2.test.TestBase;
...@@ -45,6 +45,7 @@ public class TestCsv extends TestBase { ...@@ -45,6 +45,7 @@ public class TestCsv extends TestBase {
} }
public void test() throws Exception { public void test() throws Exception {
testColumnNames();
testSpaceSeparated(); testSpaceSeparated();
testNull(); testNull();
testRandomData(); testRandomData();
...@@ -57,6 +58,15 @@ public class TestCsv extends TestBase { ...@@ -57,6 +58,15 @@ public class TestCsv extends TestBase {
deleteDb("csv"); deleteDb("csv");
} }
private void testColumnNames() throws Exception {
ResultSet rs;
rs = Csv.getInstance().read(new StringReader("Id,First Name,2x,_x2\n1,2,3"), null);
assertEquals("ID", rs.getMetaData().getColumnName(1));
assertEquals("First Name", rs.getMetaData().getColumnName(2));
assertEquals("2x", rs.getMetaData().getColumnName(3));
assertEquals("_X2", rs.getMetaData().getColumnName(4));
}
private void testSpaceSeparated() throws SQLException { private void testSpaceSeparated() throws SQLException {
deleteDb("csv"); deleteDb("csv");
File f = new File(baseDir + "/testSpace.csv"); File f = new File(baseDir + "/testSpace.csv");
...@@ -278,10 +288,10 @@ public class TestCsv extends TestBase { ...@@ -278,10 +288,10 @@ public class TestCsv extends TestBase {
ResultSet rs = Csv.getInstance().read(fileName, null, "UTF8"); ResultSet rs = Csv.getInstance().read(fileName, null, "UTF8");
ResultSetMetaData meta = rs.getMetaData(); ResultSetMetaData meta = rs.getMetaData();
assertEquals(4, meta.getColumnCount()); assertEquals(4, meta.getColumnCount());
assertEquals("a", meta.getColumnLabel(1)); assertEquals("A", meta.getColumnLabel(1));
assertEquals("b", meta.getColumnLabel(2)); assertEquals("B", meta.getColumnLabel(2));
assertEquals("c", meta.getColumnLabel(3)); assertEquals("C", meta.getColumnLabel(3));
assertEquals("d", meta.getColumnLabel(4)); assertEquals("D", meta.getColumnLabel(4));
assertTrue(rs.next()); assertTrue(rs.next());
assertEquals("201", rs.getString(1)); assertEquals("201", rs.getString(1));
assertEquals("-2", rs.getString(2)); assertEquals("-2", rs.getString(2));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论