Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.tarantool.jdbc.SQLPreparedStatement Maven / Gradle / Ivy
package org.tarantool.jdbc;
import org.tarantool.util.SQLStates;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SQLPreparedStatement extends SQLStatement implements PreparedStatement {
private static final String INVALID_CALL_MESSAGE = "The method cannot be called on a PreparedStatement.";
private static final int STREAM_WRITE_CHUNK_SIZE = 4096;
private final String sql;
private final Map parameters;
private final int autoGeneratedKeys;
private List> batchParameters = new ArrayList<>();
public SQLPreparedStatement(SQLConnection connection, String sql, int autoGeneratedKeys) throws SQLException {
super(connection);
this.sql = sql;
this.parameters = new HashMap<>();
this.autoGeneratedKeys = autoGeneratedKeys;
setPoolable(true);
}
public SQLPreparedStatement(SQLConnection connection,
String sql,
int resultSetType,
int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
super(connection, resultSetType, resultSetConcurrency, resultSetHoldability);
this.sql = sql;
this.parameters = new HashMap<>();
this.autoGeneratedKeys = NO_GENERATED_KEYS;
setPoolable(true);
}
@Override
public ResultSet executeQuery() throws SQLException {
checkNotClosed();
if (!executeInternal(autoGeneratedKeys, sql, toParametersList(parameters))) {
throw new SQLException("No results were returned", SQLStates.NO_DATA.getSqlState());
}
return resultSet;
}
@Override
public ResultSet executeQuery(String sql) throws SQLException {
checkNotClosed();
throw new SQLException(INVALID_CALL_MESSAGE);
}
@Override
public int executeUpdate() throws SQLException {
checkNotClosed();
if (executeInternal(autoGeneratedKeys, sql, toParametersList(parameters))) {
throw new SQLException(
"Result was returned but nothing was expected",
SQLStates.TOO_MANY_RESULTS.getSqlState()
);
}
return updateCount;
}
@Override
public int executeUpdate(String sql) throws SQLException {
checkNotClosed();
throw new SQLException(INVALID_CALL_MESSAGE);
}
@Override
public void setNull(int parameterIndex, int sqlType) throws SQLException {
setParameter(parameterIndex, null);
}
@Override
public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
setParameter(parameterIndex, null);
}
@Override
public void setBoolean(int parameterIndex, boolean parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setByte(int parameterIndex, byte parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setBytes(int parameterIndex, byte[] parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setShort(int parameterIndex, short parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setInt(int parameterIndex, int parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setLong(int parameterIndex, long parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setFloat(int parameterIndex, float parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setDouble(int parameterIndex, double parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setBigDecimal(int parameterIndex, BigDecimal parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setString(int parameterIndex, String parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setDate(int parameterIndex, Date parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setDate(int parameterIndex, Date parameterValue, Calendar calendar) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setTime(int parameterIndex, Time parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setTime(int parameterIndex, Time parameterValue, Calendar calendar) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setTimestamp(int parameterIndex, Timestamp parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setTimestamp(int parameterIndex, Timestamp parameterValue, Calendar calendar) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setAsciiStream(int parameterIndex, InputStream parameterValue, int length) throws SQLException {
setAsciiStream(parameterIndex, parameterValue, (long) length);
}
@Override
public void setAsciiStream(int parameterIndex, InputStream parameterValue) throws SQLException {
setCharStream(parameterIndex, parameterValue, Integer.MAX_VALUE, "ASCII");
}
@Override
public void setAsciiStream(int parameterIndex, InputStream parameterValue, long length) throws SQLException {
ensureLengthLowerBound(length);
setCharStream(parameterIndex, parameterValue, length, "ASCII");
}
@Override
public void setUnicodeStream(int parameterIndex, InputStream parameterValue, int length) throws SQLException {
ensureLengthLowerBound(length);
setCharStream(parameterIndex, parameterValue, length, "UTF-8");
}
@Override
public void setBinaryStream(int parameterIndex, InputStream parameterValue, int length) throws SQLException {
setBinaryStream(parameterIndex, parameterValue, (long) length);
}
@Override
public void setBinaryStream(int parameterIndex, InputStream parameterValue, long length) throws SQLException {
ensureLengthLowerBound(length);
setBinStream(parameterIndex, parameterValue, length);
}
@Override
public void setBinaryStream(int parameterIndex, InputStream parameterValue) throws SQLException {
setBinStream(parameterIndex, parameterValue, Integer.MAX_VALUE);
}
@Override
public void clearParameters() throws SQLException {
parameters.clear();
}
@Override
public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
setObject(parameterIndex, x, targetSqlType, -1);
}
@Override
public void setObject(int parameterIndex, Object value) throws SQLException {
setParameter(parameterIndex, value);
}
@Override
public void setObject(int parameterIndex,
Object parameterValue,
int targetSqlType,
int scaleOrLength) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
private void setParameter(int parameterIndex, Object value) throws SQLException {
checkNotClosed();
parameters.put(parameterIndex, value);
}
@Override
public boolean execute() throws SQLException {
checkNotClosed();
return executeInternal(autoGeneratedKeys, sql, toParametersList(parameters));
}
@Override
public boolean execute(String sql) throws SQLException {
checkNotClosed();
throw new SQLException(INVALID_CALL_MESSAGE);
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
setCharacterStream(parameterIndex, reader, (long) length);
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
ensureLengthLowerBound(length);
setCharStream(parameterIndex, reader, length);
}
@Override
public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
setCharStream(parameterIndex, reader, Integer.MAX_VALUE);
}
@Override
public void setRef(int parameterIndex, Ref x) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setBlob(int parameterIndex, Blob x) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setClob(int parameterIndex, Clob x) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setClob(int parameterIndex, Reader reader) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setArray(int parameterIndex, Array x) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public ResultSetMetaData getMetaData() throws SQLException {
if (resultSet != null && !resultSet.isClosed()) {
return resultSet.getMetaData();
}
// XXX: it's required a support of dry-run mode to obtain
// a statement metadata without real query execution.
// see https://github.com/tarantool/tarantool/issues/3292
return null;
}
@Override
public void setURL(int parameterIndex, URL parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue.toString());
}
@Override
public ParameterMetaData getParameterMetaData() throws SQLException {
return null;
}
@Override
public void setRowId(int parameterIndex, RowId x) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setNString(int parameterIndex, String parameterValue) throws SQLException {
setParameter(parameterIndex, parameterValue);
}
@Override
public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
setCharacterStream(parameterIndex, value, length);
}
@Override
public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
setCharacterStream(parameterIndex, value);
}
@Override
public void setNClob(int parameterIndex, NClob value) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setNClob(int parameterIndex, Reader reader) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void addBatch(String sql) throws SQLException {
checkNotClosed();
throw new SQLException(INVALID_CALL_MESSAGE);
}
@Override
public void addBatch() throws SQLException {
checkNotClosed();
// shadow copy of the current parameters
batchParameters.add(new HashMap<>(parameters));
}
@Override
public int[] executeBatch() throws SQLException {
checkNotClosed();
try {
List queries = new ArrayList<>();
for (Map p : batchParameters) {
SQLQueryHolder of = SQLQueryHolder.of(sql, toParametersList(p));
queries.add(of);
}
return executeBatchInternal(queries);
} finally {
batchParameters.clear();
}
}
@Override
public void clearBatch() throws SQLException {
checkNotClosed();
batchParameters.clear();
}
private Object[] toParametersList(Map parameters) throws SQLException {
Object[] objects = new Object[parameters.size()];
for (int i = 1; i <= parameters.size(); i++) {
if (parameters.containsKey(i)) {
objects[i - 1] = parameters.get(i);
} else {
throw new SQLException("Parameter " + i + " is missing");
}
}
return objects;
}
private void ensureLengthLowerBound(long length) throws SQLException {
if (length < 0) {
throw new SQLException("Stream size cannot be negative", SQLStates.INVALID_PARAMETER_VALUE.getSqlState());
}
}
private void ensureLengthUpperBound(long length) throws SQLException {
if (length > Integer.MAX_VALUE) {
throw new SQLException("Stream size is too large", SQLStates.INVALID_PARAMETER_VALUE.getSqlState());
}
}
private void setCharStream(int parameterIndex,
InputStream parameterValue,
long length,
String encoding) throws SQLException {
ensureLengthUpperBound(length);
try {
byte[] bytes = convertToBytes(parameterValue, length);
setParameter(parameterIndex, new String(bytes, 0, bytes.length, encoding));
} catch (UnsupportedEncodingException e) {
throw new SQLException("Unsupported encoding", SQLStates.INVALID_PARAMETER_VALUE.getSqlState(), e);
}
}
private void setCharStream(int parameterIndex, Reader reader, long length) throws SQLException {
ensureLengthUpperBound(length);
try {
StringBuilder value = new StringBuilder(STREAM_WRITE_CHUNK_SIZE);
char[] buffer = new char[STREAM_WRITE_CHUNK_SIZE];
int totalRead = 0;
int charsRead;
while (totalRead < length &&
(charsRead = reader.read(buffer, 0,
(int) Math.min(length - totalRead, STREAM_WRITE_CHUNK_SIZE))) != -1) {
value.append(buffer, 0, charsRead);
totalRead += charsRead;
}
setParameter(parameterIndex, value.toString());
} catch (IOException e) {
throw new SQLException("Cannot read from the reader", SQLStates.INVALID_PARAMETER_VALUE.getSqlState(), e);
}
}
private void setBinStream(int parameterIndex,
InputStream parameterValue,
long length) throws SQLException {
ensureLengthUpperBound(length);
setBytes(parameterIndex, convertToBytes(parameterValue, length));
}
private byte[] convertToBytes(InputStream parameterValue, long length) throws SQLException {
try {
int bytesRead;
int totalRead = 0;
byte[] buffer = new byte[STREAM_WRITE_CHUNK_SIZE];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(STREAM_WRITE_CHUNK_SIZE);
while (totalRead < length &&
(bytesRead = parameterValue.read(buffer, 0,
(int) Math.min(length - totalRead, STREAM_WRITE_CHUNK_SIZE))) != -1) {
outputStream.write(buffer, 0, bytesRead);
totalRead += bytesRead;
}
return outputStream.toByteArray();
} catch (IOException e) {
throw new SQLException("Cannot read stream", SQLStates.INVALID_PARAMETER_VALUE.getSqlState(), e);
}
}
}