libdb/lang/sql/jdbc/SQLite/JDBC2z/JDBCStatement.java
2011-09-13 13:44:24 -04:00

372 lines
8.2 KiB
Java

package SQLite.JDBC2z;
import java.sql.BatchUpdateException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.ArrayList;
public class JDBCStatement implements java.sql.Statement {
protected JDBCConnection conn;
protected JDBCResultSet rs;
protected int updcnt;
protected int maxrows = 0;
private ArrayList<String> batch;
public JDBCStatement(JDBCConnection conn) {
this.conn = conn;
this.updcnt = 0;
this.rs = null;
this.batch = null;
}
@Override
public void setFetchSize(int fetchSize) throws SQLException {
if (fetchSize != 1) {
throw new SQLException("fetch size not 1");
}
}
@Override
public int getFetchSize() throws SQLException {
return 1;
}
@Override
public int getMaxRows() throws SQLException {
return maxrows;
}
@Override
public void setMaxRows(int max) throws SQLException {
if (max < 0) {
throw new SQLException("max must be >= 0 (was " + max + ")");
}
maxrows = max;
}
@Override
public void setFetchDirection(int fetchDirection) throws SQLException {
throw new SQLException("not supported");
}
@Override
public int getFetchDirection() throws SQLException {
return ResultSet.FETCH_UNKNOWN;
}
@Override
public int getResultSetConcurrency() throws SQLException {
return ResultSet.CONCUR_READ_ONLY;
}
@Override
public int getResultSetType() throws SQLException {
return ResultSet.TYPE_SCROLL_INSENSITIVE;
}
@Override
public void setQueryTimeout(int seconds) throws SQLException {
if (isClosed()) {
throw new SQLException("can't set query timeout on " +
"a closed statement");
} else if (seconds < 0) {
throw new SQLException("can't set a query timeout of " +
"less than 0 seconds");
} else if (seconds == 0) {
conn.timeout = 5000;
} else {
conn.timeout = seconds * 1000;
}
}
@Override
public int getQueryTimeout() throws SQLException {
return conn.timeout / 1000;
}
@Override
public ResultSet getResultSet() throws SQLException {
return rs;
}
ResultSet executeQuery(String sql, String args[], boolean updonly)
throws SQLException {
SQLite.TableResult tr = null;
if (rs != null) {
rs.close();
rs = null;
}
updcnt = -1;
if (conn == null || conn.db == null) {
throw new SQLException("stale connection");
}
int busy = 0;
boolean starttrans = !conn.autocommit && !conn.intrans;
while (true) {
try {
if (starttrans) {
conn.db.exec("BEGIN TRANSACTION", null);
conn.intrans = true;
}
if (args == null) {
if (updonly) {
conn.db.exec(sql, null);
} else {
tr = conn.db.get_table(sql, maxrows);
}
} else {
if (updonly) {
conn.db.exec(sql, null, args);
} else {
tr = conn.db.get_table(sql, maxrows, args);
}
}
updcnt = (int) conn.db.changes();
} catch (SQLite.Exception e) {
if (conn.db.is3() &&
conn.db.last_error() == SQLite.Constants.SQLITE_BUSY &&
conn.busy3(conn.db, ++busy)) {
try {
if (starttrans && conn.intrans) {
conn.db.exec("ROLLBACK", null);
conn.intrans = false;
}
} catch (SQLite.Exception ee) {
}
try {
int ms = 20 + busy * 10;
if (ms > 1000) {
ms = 1000;
}
synchronized (this) {
this.wait(ms);
}
} catch (java.lang.Exception eee) {
}
continue;
}
throw new SQLException(e);
}
break;
}
if (!updonly && tr == null) {
throw new SQLException("no result set produced");
}
if (!updonly && tr != null) {
rs = new JDBCResultSet(new TableResultX(tr), this);
}
return rs;
}
@Override
public ResultSet executeQuery(String sql) throws SQLException {
return executeQuery(sql, null, false);
}
@Override
public boolean execute(String sql) throws SQLException {
return executeQuery(sql) != null;
}
@Override
public void cancel() throws SQLException {
if (conn == null || conn.db == null) {
throw new SQLException("stale connection");
}
conn.db.interrupt();
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public Connection getConnection() throws SQLException {
return conn;
}
@Override
public void addBatch(String sql) throws SQLException {
if (batch == null) {
batch = new ArrayList<String>(1);
}
batch.add(sql);
}
@Override
public int[] executeBatch() throws SQLException {
if (batch == null) {
return new int[0];
}
int[] ret = new int[batch.size()];
for (int i = 0; i < ret.length; i++) {
ret[i] = EXECUTE_FAILED;
}
int errs = 0;
Exception cause = null;
for (int i = 0; i < ret.length; i++) {
try {
execute(batch.get(i));
ret[i] = updcnt;
} catch (SQLException e) {
++errs;
if (cause == null) {
cause = e;
}
}
}
if (errs > 0) {
throw new BatchUpdateException("batch failed", ret, cause);
}
return ret;
}
@Override
public void clearBatch() throws SQLException {
if (batch != null) {
batch.clear();
batch = null;
}
}
@Override
public void close() throws SQLException {
clearBatch();
conn = null;
}
@Override
public int executeUpdate(String sql) throws SQLException {
executeQuery(sql, null, true);
return updcnt;
}
@Override
public int getMaxFieldSize() throws SQLException {
return 0;
}
@Override
public boolean getMoreResults() throws SQLException {
if (rs != null) {
rs.close();
rs = null;
}
return false;
}
@Override
public int getUpdateCount() throws SQLException {
return updcnt;
}
@Override
public SQLWarning getWarnings() throws SQLException {
return null;
}
@Override
public void setCursorName(String name) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setEscapeProcessing(boolean enable) throws SQLException {
throw new SQLException("not supported");
}
@Override
public void setMaxFieldSize(int max) throws SQLException {
throw new SQLException("not supported");
}
@Override
public boolean getMoreResults(int x) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public ResultSet getGeneratedKeys() throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public int executeUpdate(String sql, int autokeys)
throws SQLException {
if (autokeys != Statement.NO_GENERATED_KEYS) {
throw new SQLFeatureNotSupportedException("generated keys not supported");
}
return executeUpdate(sql);
}
@Override
public int executeUpdate(String sql, int colIndexes[])
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public int executeUpdate(String sql, String colIndexes[])
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public boolean execute(String sql, int autokeys)
throws SQLException {
if (autokeys != Statement.NO_GENERATED_KEYS) {
throw new SQLFeatureNotSupportedException("autogenerated keys not supported");
}
return execute(sql);
}
@Override
public boolean execute(String sql, int colIndexes[])
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public boolean execute(String sql, String colIndexes[])
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public int getResultSetHoldability() throws SQLException {
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
@Override
public boolean isClosed() throws SQLException {
return conn == null;
}
@Override
public void setPoolable(boolean yes) throws SQLException {
if (yes) {
throw new SQLException("poolable statements not supported");
}
}
@Override
public boolean isPoolable() throws SQLException {
return false;
}
@Override
public <T> T unwrap(java.lang.Class<T> iface) throws SQLException {
throw new SQLException("unsupported");
}
@Override
public boolean isWrapperFor(java.lang.Class iface) throws SQLException {
return false;
}
}