OracleParameterBinders.java
package org.codefilarete.stalactite.sql.oracle.statement.binder;
import java.io.IOException;
import java.sql.Blob;
import java.sql.JDBCType;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.time.OffsetDateTime;
import java.time.ZonedDateTime;
import org.codefilarete.stalactite.sql.statement.binder.DefaultParameterBinders;
import org.codefilarete.stalactite.sql.statement.binder.NullAwareParameterBinder;
import org.codefilarete.stalactite.sql.statement.binder.ParameterBinder;
import org.codefilarete.stalactite.sql.statement.binder.PreparedStatementWriter;
import org.codefilarete.tool.io.IOs;
/**
* @author Guillaume Mary
*/
public final class OracleParameterBinders {
/**
* As of JDBC4, SQLite doesn't support setBinaryStream, therefore we use setBytes(..)
*/
public static final ParameterBinder<Blob> BLOB_BINDER = new NullAwareParameterBinder<>(
DefaultParameterBinders.BLOB_BINDER, new BlobWriter());
// Can also be done that wrapping setBinaryStream(..), but it doesn't call setBlob(..) which is preferred to match Binder philosophy
// DefaultParameterBinders.BINARYSTREAM_BINDER.wrap(inputStream -> new InMemoryBlobSupport(IOs.toByteArray(inputStream)), Blob::getBinaryStream);
/**
* Oracle native support for {@link ZonedDateTime}
*/
public static final ParameterBinder<ZonedDateTime> ZONED_DATE_TIME_BINDER = new NullAwareParameterBinder<>(
new JdbcTypeResultSetReader<>(ZonedDateTime.class),
new JdbcTypePreparedStatementWriter<>(ZonedDateTime.class, JDBCType.TIMESTAMP_WITH_TIMEZONE));
/**
* Oracle native support for {@link OffsetDateTime}
*/
public static final ParameterBinder<OffsetDateTime> OFFSET_DATE_TIME_BINDER = new NullAwareParameterBinder<>(
new JdbcTypeResultSetReader<>(OffsetDateTime.class),
new JdbcTypePreparedStatementWriter<>(OffsetDateTime.class, JDBCType.TIMESTAMP_WITH_TIMEZONE));
/**
* Dedicated writer for Oracle Blobs that handles non Oracle Blob to avoid a ClassCastException meaning that
* Oracle only support incoming oracle.sql.BLOB
*
* @author Guillaume Mary
*/
private static class BlobWriter implements PreparedStatementWriter<Blob> {
@Override
public Class<Blob> getType() {
return Blob.class;
}
@Override
public void set(PreparedStatement preparedStatement, int valueIndex, Blob blob) throws SQLException {
oracle.sql.BLOB oracleBlob;
if (blob instanceof oracle.sql.BLOB) {
oracleBlob = (oracle.sql.BLOB) blob;
} else {
oracleBlob = (oracle.sql.BLOB) preparedStatement.getConnection().createBlob();
try {
// note that setBytes(byte[]) is not supported
oracleBlob.setBytes(1, IOs.toByteArray(blob.getBinaryStream()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
preparedStatement.setBlob(valueIndex, oracleBlob);
// note that we shouldn't free the blob here since transaction is not yet complete
// oracleBlob.free();
}
}
private OracleParameterBinders() {
}
}