提交 f9d3ade6 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 446f59df
...@@ -40,7 +40,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch. ...@@ -40,7 +40,8 @@ Hypersonic SQL or HSQLDB. H2 is built from scratch.
<h3>Version 1.0 (Current)</h3> <h3>Version 1.0 (Current)</h3>
<h3>Version 1.0.60 (2007-10-?)</h3><ul> <h3>Version 1.0.60 (2007-10-?)</h3><ul>
<li>Prepared statements could not be used after data definition statements (creating tables and so on). Fixed. <li>CSV: New methods to set the escape character and field delimiter in the Csv tool and the CSVWRITE and CSVREAD methods.
</li><li>Prepared statements could not be used after data definition statements (creating tables and so on). Fixed.
</li><li>PreparedStatement.setMaxRows could not be changed to a higher value after the statement was executed. </li><li>PreparedStatement.setMaxRows could not be changed to a higher value after the statement was executed.
</li><li>The H2 Console could not connect twice to the same H2 embedded database at the same time. Fixed. </li><li>The H2 Console could not connect twice to the same H2 embedded database at the same time. Fixed.
</li><li>CSVREAD, RUNSCRIPT and so on now support URLs as well, using </li><li>CSVREAD, RUNSCRIPT and so on now support URLs as well, using
......
...@@ -799,12 +799,20 @@ public class Function extends Expression implements FunctionCall { ...@@ -799,12 +799,20 @@ public class Function extends Expression implements FunctionCall {
String columnList = v1 == null ? null : v1.getString(); String columnList = v1 == null ? null : v1.getString();
String charset = v2 == null ? null : v2.getString(); String charset = v2 == null ? null : v2.getString();
String fieldSeparatorRead = v3 == null ? null : v3.getString(); String fieldSeparatorRead = v3 == null ? null : v3.getString();
String fieldDelimiter = v4 == null ? null : v4.getString();
String escapeCharacter = v5 == null ? null : v5.getString();
Csv csv = Csv.getInstance(); Csv csv = Csv.getInstance();
char fieldSeparator = ','; char fieldSeparator = csv.getFieldSeparatorRead();
if (fieldSeparatorRead != null && fieldSeparatorRead.length() > 0) { if (fieldSeparatorRead != null && fieldSeparatorRead.length() > 0) {
fieldSeparator = fieldSeparatorRead.charAt(0); fieldSeparator = fieldSeparatorRead.charAt(0);
csv.setFieldSeparatorRead(fieldSeparator); csv.setFieldSeparatorRead(fieldSeparator);
} }
if (fieldDelimiter != null && fieldDelimiter.length() > 0) {
csv.setFieldDelimiter(fieldDelimiter.charAt(0));
}
if (escapeCharacter != null && escapeCharacter.length() > 0) {
csv.setEscapeCharacter(escapeCharacter.charAt(0));
}
String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true); String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true);
ValueResultSet vr = ValueResultSet.get(csv.read(fileName, columns, charset)); ValueResultSet vr = ValueResultSet.get(csv.read(fileName, columns, charset));
return vr; return vr;
...@@ -823,10 +831,18 @@ public class Function extends Expression implements FunctionCall { ...@@ -823,10 +831,18 @@ public class Function extends Expression implements FunctionCall {
Connection conn = session.createConnection(false); Connection conn = session.createConnection(false);
String charset = v2 == null ? null : v2.getString(); String charset = v2 == null ? null : v2.getString();
String fieldSeparatorWrite = v3 == null ? null : v3.getString(); String fieldSeparatorWrite = v3 == null ? null : v3.getString();
String fieldDelimiter = v4 == null ? null : v4.getString();
String escapeCharacter = v5 == null ? null : v5.getString();
Csv csv = Csv.getInstance(); Csv csv = Csv.getInstance();
if (fieldSeparatorWrite != null) { if (fieldSeparatorWrite != null) {
csv.setFieldSeparatorWrite(fieldSeparatorWrite); csv.setFieldSeparatorWrite(fieldSeparatorWrite);
} }
if (fieldDelimiter != null && fieldDelimiter.length() > 0) {
csv.setFieldDelimiter(fieldDelimiter.charAt(0));
}
if (escapeCharacter != null && escapeCharacter.length() > 0) {
csv.setEscapeCharacter(escapeCharacter.charAt(0));
}
int rows = csv.write(conn, v0.getString(), v1.getString(), charset); int rows = csv.write(conn, v0.getString(), v1.getString(), charset);
return ValueInt.get(rows); return ValueInt.get(rows);
} }
...@@ -1549,12 +1565,20 @@ public class Function extends Expression implements FunctionCall { ...@@ -1549,12 +1565,20 @@ public class Function extends Expression implements FunctionCall {
String columnList = args.length < 2 ? null : args[1].getValue(session).getString(); String columnList = args.length < 2 ? null : args[1].getValue(session).getString();
String charset = args.length < 3 ? null : args[2].getValue(session).getString(); String charset = args.length < 3 ? null : args[2].getValue(session).getString();
String fieldSeparatorRead = args.length < 4 ? null : args[3].getValue(session).getString(); String fieldSeparatorRead = args.length < 4 ? null : args[3].getValue(session).getString();
String fieldDelimiter = args.length < 5 ? null : args[4].getValue(session).getString();
String escapeCharacter = args.length < 6 ? null : args[5].getValue(session).getString();
Csv csv = Csv.getInstance(); Csv csv = Csv.getInstance();
char fieldSeparator = ','; char fieldSeparator = ',';
if (fieldSeparatorRead != null && fieldSeparatorRead.length() > 0) { if (fieldSeparatorRead != null && fieldSeparatorRead.length() > 0) {
fieldSeparator = fieldSeparatorRead.charAt(0); fieldSeparator = fieldSeparatorRead.charAt(0);
csv.setFieldSeparatorRead(fieldSeparator); csv.setFieldSeparatorRead(fieldSeparator);
} }
if (fieldDelimiter != null && fieldDelimiter.length() > 0) {
csv.setFieldDelimiter(fieldDelimiter.charAt(0));
}
if (escapeCharacter != null && escapeCharacter.length() > 0) {
csv.setEscapeCharacter(escapeCharacter.charAt(0));
}
String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true); String[] columns = StringUtils.arraySplit(columnList, fieldSeparator, true);
ResultSet rs = csv.read(fileName, columns, charset); ResultSet rs = csv.read(fileName, columns, charset);
ValueResultSet vr = ValueResultSet.getCopy(rs, 0); ValueResultSet vr = ValueResultSet.getCopy(rs, 0);
......
...@@ -2509,7 +2509,7 @@ CURRVAL('TEST_SEQ') ...@@ -2509,7 +2509,7 @@ CURRVAL('TEST_SEQ')
" "
"Functions (System)","CSVREAD"," "Functions (System)","CSVREAD","
CSVREAD(fileNameString [, columnNamesString [, charsetString [, fieldSeparatorString]]]): resultSet CSVREAD(fileNameString [, columnNamesString [, charsetString [, fieldSeparatorString [, fieldDelimiterString [, escapeCharacterString]]]]]): resultSet
"," ","
Returns the result set of reading the CSV (comma separated values) file. Returns the result set of reading the CSV (comma separated values) file.
If the column names are specified (a comma separated list of column names), If the column names are specified (a comma separated list of column names),
...@@ -2524,11 +2524,12 @@ CALL CSVREAD('test.csv') ...@@ -2524,11 +2524,12 @@ CALL CSVREAD('test.csv')
" "
"Functions (System)","CSVWRITE"," "Functions (System)","CSVWRITE","
CSVWRITE(fileNameString, queryString [, charsetString [, fieldSeparatorString]]): null CSVWRITE(fileNameString, queryString [, charsetString [, fieldSeparatorString [, fieldDelimiterString [, escapeCharacterString]]]]): int
"," ","
Writes a CSV (comma separated values). Writes a CSV (comma separated values).
The file is overwritten if it exists. The file is overwritten if it exists.
The default charset is the default value for this system, and the default field separator is a comma. The default charset is the default value for this system, and the default field separator is a comma.
The returned value is the number or rows written.
Admin rights are required to execute this command. Admin rights are required to execute this command.
"," ","
CALL CSVWRITE('test.csv', 'SELECT * FROM TEST') CALL CSVWRITE('test.csv', 'SELECT * FROM TEST')
...@@ -2560,7 +2561,7 @@ GREATEST(A, B, C) ...@@ -2560,7 +2561,7 @@ GREATEST(A, B, C)
" "
"Functions (System)","IDENTITY"," "Functions (System)","IDENTITY","
IDENTITY(): int IDENTITY(): long
"," ","
Returns the last inserted identity value for this session. Returns the last inserted identity value for this session.
"," ","
......
...@@ -146,12 +146,9 @@ public class Csv implements SimpleRowSource { ...@@ -146,12 +146,9 @@ public class Csv implements SimpleRowSource {
* 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.
* *
* @param fileName * @param fileName the file name
* the file name * @param colNames or null if the column names should be read from the CSV file
* @param colNames * @param charset the charset or null to use UTF-8
* or null if the column names should be read from the CSV file
* @param charset
* the charset or null to use UTF-8
* @return the result set * @return the result set
* @throws SQLException * @throws SQLException
*/ */
...@@ -169,13 +166,10 @@ public class Csv implements SimpleRowSource { ...@@ -169,13 +166,10 @@ public class Csv implements SimpleRowSource {
* result set are created on demand, that means the reader is kept open * result set are created on demand, that means the reader is kept open
* until all rows are read or the result set is closed. * until all rows are read or the result set is closed.
* *
* @param reader * @param reader the reader
* the reader * @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
* @return the result set * @return the result set
* @throws SQLException, * @throws SQLException, IOException
* IOException
*/ */
public ResultSet read(Reader reader, String[] colNames) throws SQLException, IOException { public ResultSet read(Reader reader, String[] colNames) throws SQLException, IOException {
init(null, null); init(null, null);
...@@ -500,39 +494,103 @@ public class Csv implements SimpleRowSource { ...@@ -500,39 +494,103 @@ public class Csv implements SimpleRowSource {
IOUtils.closeSilently(writer); IOUtils.closeSilently(writer);
writer = null; writer = null;
} }
/**
* INTERNAL
*/
public void reset() throws SQLException {
throw new SQLException("Method is not supported", "CSV");
}
/** /**
* Override the field separator for writing. The default is ",". * Override the field separator for writing. The default is ",".
* *
* @param fieldSeparatorWrite * @param fieldSeparatorWrite the field separator
*/ */
public void setFieldSeparatorWrite(String fieldSeparatorWrite) { public void setFieldSeparatorWrite(String fieldSeparatorWrite) {
this.fieldSeparatorWrite = fieldSeparatorWrite; this.fieldSeparatorWrite = fieldSeparatorWrite;
} }
/**
* Get the current field reparator for writing.
*
* @return the field separator
*/
public String getFieldSeparatorWrite() {
return fieldSeparatorWrite;
}
/** /**
* Override the field separator for reading. The default is ','. * Override the field separator for reading. The default is ','.
* *
* @param fieldSeparatorRead * @param fieldSeparatorRead the field separator
*/ */
public void setFieldSeparatorRead(char fieldSeparatorRead) { public void setFieldSeparatorRead(char fieldSeparatorRead) {
this.fieldSeparatorRead = fieldSeparatorRead; this.fieldSeparatorRead = fieldSeparatorRead;
} }
/**
* Get the current field separator for reading.
*
* @return the field separator
*/
public char getFieldSeparatorRead() {
return fieldSeparatorRead;
}
/**
* Get the current row separator for writing.
*
* @return the row separator
*/
public String getRowSeparatorWrite() {
return rowSeparatorWrite;
}
/** /**
* Override the end-of-row marker for writing. The default is null. * Override the end-of-row marker for writing. The default is null.
* After writing the end-of-row marker, a line feed is written (\n or \r\n depending on the system settings).
* *
* @param rowSeparatorWrite * @param rowSeparatorWrite the row separator
*/ */
public void setRowSeparatorWrite(String rowSeparatorWrite) { public void setRowSeparatorWrite(String rowSeparatorWrite) {
this.rowSeparatorWrite = rowSeparatorWrite; this.rowSeparatorWrite = rowSeparatorWrite;
} }
/** /**
* INTERNAL * Set the field delimiter. The default is " (a double quote).
*
* @param fieldDelimiter the field delimiter
*/ */
public void reset() throws SQLException { public void setFieldDelimiter(char fieldDelimiter) {
throw new SQLException("Method is not supported", "CSV"); this.fieldDelimiter = fieldDelimiter;
}
/**
* Get the current field delimiter.
*
* @return the field delimiter
*/
public char getFieldDelimiter() {
return fieldDelimiter;
}
/**
* Set the escape character (used to escape the field delimiter). The default is " (a double quote).
*
* @param escapeCharacter the escape character
*/
public void setEscapeCharacter(char escapeCharacter) {
this.escapeCharacter = escapeCharacter;
}
/**
* Get the current escape character.
*
* @return the escape character
*/
public char getEscapeCharacter() {
return escapeCharacter;
} }
} }
...@@ -17,11 +17,42 @@ import org.h2.tools.Csv; ...@@ -17,11 +17,42 @@ import org.h2.tools.Csv;
public class TestCsv extends TestBase { public class TestCsv extends TestBase {
public void test() throws Exception { public void test() throws Exception {
testFieldDelimiter();
testAsTable(); testAsTable();
testWriteRead(); testWriteRead();
testRead(); testRead();
testPipe(); testPipe();
} }
private void testFieldDelimiter() throws Exception {
File f = new File(baseDir + "/test.csv");
f.delete();
RandomAccessFile file = new RandomAccessFile(f, "rw");
file.write("'A'; 'B'\n\'It\\'s nice\'; '\nHello\\*\n'".getBytes());
file.close();
Connection conn = getConnection("csv");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select * from csvread('" + baseDir + "/test.csv', null, null, ';', '''', '\\')");
ResultSetMetaData meta = rs.getMetaData();
check(meta.getColumnCount(), 2);
check(meta.getColumnLabel(1), "A");
check(meta.getColumnLabel(2), "B");
check(rs.next());
check(rs.getString(1), "It's nice");
check(rs.getString(2), "\nHello*\n");
checkFalse(rs.next());
stat.execute("call csvwrite('" + baseDir + "/test2.csv', 'select * from csvread(''" + baseDir + "/test.csv'', null, null, '';'', '''''''', ''\\'')', null, '+', '*', '#')");
rs = stat.executeQuery("select * from csvread('" + baseDir + "/test2.csv', null, null, '+', '*', '#')");
meta = rs.getMetaData();
check(meta.getColumnCount(), 2);
check(meta.getColumnLabel(1), "A");
check(meta.getColumnLabel(2), "B");
check(rs.next());
check(rs.getString(1), "It's nice");
check(rs.getString(2), "\nHello*\n");
checkFalse(rs.next());
conn.close();
}
private void testPipe() throws Exception { private void testPipe() throws Exception {
deleteDb("csv"); deleteDb("csv");
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论