org.relique.jdbc.csv.CsvStatement Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of csvjdbc Show documentation
Show all versions of csvjdbc Show documentation
a Java JDBC driver for reading comma-separated-value files
/*
* CsvJdbc - a JDBC driver for CSV files
* Copyright (C) 2001 Jonathan Ackerman
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.relique.jdbc.csv;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.relique.io.CryptoFilter;
import org.relique.io.DataReader;
import org.relique.io.EncryptedFileInputStream;
import org.relique.io.FileSetInputStream;
import org.relique.io.ListDataReader;
import org.relique.io.TableReader;
import org.relique.jdbc.dbf.DbfReader;
/**
* This class implements the java.sql.Statement JDBC interface for the
* CsvJdbc driver.
*/
public class CsvStatement implements Statement
{
/*
* Key for column name in database rows for accessing CsvStatement.
*/
public static final String STATEMENT_COLUMN_NAME = "@STATEMENT";
private CsvConnection connection;
protected ResultSet lastResultSet = null;
protected List multipleParsers = null;
private int maxRows = 0;
private int fetchSize = 1;
private int queryTimeout = Integer.MAX_VALUE;
private int fetchDirection = ResultSet.FETCH_FORWARD;
private boolean closed;
protected int resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE;
/**
* Creates new Statement for use in executing SQL statements.
*
* @param connection
* database connection to create statement for.
* @param resultSetType
* either ResultSet.TYPE_SCROLL_INSENSITIVE or
* ResultSet.TYPE_SCROLL_SENSITIVE.
*/
protected CsvStatement(CsvConnection connection, int resultSetType)
{
CsvDriver.writeLog("CsvStatement() - connection="
+ connection);
CsvDriver.writeLog("CsvStatement() - Asked for "
+ (resultSetType == ResultSet.TYPE_SCROLL_SENSITIVE ? "Scrollable"
: "Not Scrollable"));
this.connection = connection;
this.resultSetType = resultSetType;
}
protected void checkOpen() throws SQLException
{
if (closed)
throw new SQLException(CsvResources.getString("statementClosed"));
}
@Override
public void setMaxFieldSize(int p0) throws SQLException
{
throw new SQLException(CsvResources.getString("methodNotSupported") + ": setMaxFieldSize(int)");
}
@Override
public void setMaxRows(int max) throws SQLException
{
checkOpen();
maxRows = max;
}
@Override
public void setEscapeProcessing(boolean enable) throws SQLException
{
throw new SQLException(CsvResources.getString("methodNotSupported") + ": setEscapeProcessing(boolean)");
}
@Override
public void setQueryTimeout(int seconds) throws SQLException
{
queryTimeout = seconds;
}
@Override
public void setCursorName(String name) throws SQLException
{
throw new SQLException(CsvResources.getString("methodNotSupported") + ": setCursorName(String)");
}
@Override
public void setFetchDirection(int direction) throws SQLException
{
checkOpen();
if (direction == ResultSet.FETCH_FORWARD ||
direction == ResultSet.FETCH_REVERSE ||
direction == ResultSet.FETCH_UNKNOWN)
{
this.fetchDirection = direction;
}
else
{
throw new SQLException(CsvResources.getString("unsupportedDirection") + ": " + direction);
}
}
@Override
public void setFetchSize(int rows) throws SQLException
{
checkOpen();
this.fetchSize = rows;
}
@Override
public int getMaxFieldSize() throws SQLException
{
throw new SQLException(CsvResources.getString("methodNotSupported") + ": getMaxFieldSize()");
}
@Override
public int getMaxRows() throws SQLException
{
checkOpen();
return maxRows;
}
@Override
public int getQueryTimeout() throws SQLException
{
checkOpen();
return queryTimeout;
}
@Override
public SQLWarning getWarnings() throws SQLException
{
checkOpen();
return null;
}
@Override
public ResultSet getResultSet() throws SQLException
{
checkOpen();
return lastResultSet;
}
@Override
public int getUpdateCount() throws SQLException
{
checkOpen();
/*
* Driver is read-only, so no updates are possible.
*/
return -1;
}
@Override
public boolean getMoreResults() throws SQLException
{
checkOpen();
try
{
/*
* Close any ResultSet that is currently open.
*/
if (lastResultSet != null)
lastResultSet.close();
}
finally
{
lastResultSet = null;
}
boolean retval;
if (multipleParsers != null && multipleParsers.size() > 0)
{
/*
* There are multiple SELECT statements being executed. Go to the next one.
*/
lastResultSet = executeParsedQuery(multipleParsers.remove(0));
retval = true;
}
else
{
retval = false;
}
return retval;
}
@Override
public int getFetchDirection() throws SQLException
{
checkOpen();
return fetchDirection;
}
@Override
public int getFetchSize() throws SQLException
{
checkOpen();
return fetchSize;
}
@Override
public int getResultSetConcurrency() throws SQLException
{
checkOpen();
return ResultSet.CONCUR_READ_ONLY;
}
@Override
public int getResultSetType() throws SQLException
{
checkOpen();
return this.resultSetType;
}
@Override
public Connection getConnection() throws SQLException
{
checkOpen();
return connection;
}
@Override
public ResultSet executeQuery(String sql) throws SQLException
{
checkOpen();
CsvDriver.writeLog("CsvStatement:executeQuery() - sql= " + sql);
/*
* Close any previous ResultSet, as required by JDBC.
*/
try
{
if (lastResultSet != null)
lastResultSet.close();
}
finally
{
lastResultSet = null;
multipleParsers = null;
}
SqlParser parser = new SqlParser();
try
{
parser.parse(sql);
}
catch (Exception e)
{
throw new SQLException(CsvResources.getString("syntaxError") + ": " + e.getMessage());
}
return executeParsedQuery(parser);
}
protected ResultSet executeParsedQuery(SqlParser parser)
throws SQLException
{
HashMap parentobjectEnvironment = new HashMap();
ResultSet resultSet = executeParsedQuery(parser, parentobjectEnvironment);
lastResultSet = resultSet;
return resultSet;
}
protected ResultSet executeParsedQuery(SqlParser parser, Map parentobjectEnvironment)
throws SQLException
{
if (parser.getTableNames().size() > 1)
throw new SQLException(CsvResources.getString("joinNotSupported"));
String tableName = null;
if (parser.getTableNames().size() > 0)
tableName = parser.getTableNames().get(0);
String tableAlias = null;
if (parser.getTableAliases().size() > 0)
tableAlias = parser.getTableAliases().get(0);
String path = connection.getPath();
TableReader tableReader = connection.getTableReader();
if (path != null)
CsvDriver.writeLog("Connection Path: " + path);
else
CsvDriver.writeLog("Connection TableReader: " + tableReader.getClass().getName());
CsvDriver.writeLog("Parser Table Name: " + tableName);
CsvDriver.writeLog("Connection Extension: " + connection.getExtension());
DataReader reader = null;
String fileName = null;
if (tableName == null)
{
/*
* Create an empty dataset with one row.
*/
String[] columnNames = new String[0];
String[] columnTypes = new String[0];
ArrayList