SimpleConnection.java
package org.itsallcode.jdbc;
import java.sql.Connection;
import org.itsallcode.jdbc.batch.*;
import org.itsallcode.jdbc.dialect.DbDialect;
import org.itsallcode.jdbc.metadata.DbMetaData;
import org.itsallcode.jdbc.resultset.RowMapper;
import org.itsallcode.jdbc.resultset.SimpleResultSet;
import org.itsallcode.jdbc.resultset.generic.Row;
/**
* A simplified version of a JDBC {@link Connection}. Create new connections
* with
* <ul>
* <li>{@link ConnectionFactory#create(String, String, String)}</li>
* <li>or {@link DataSourceConnectionFactory#getConnection()}</li>
* <li>or {@link #wrap(Connection, DbDialect)}</li>
* </ul>
*/
public class SimpleConnection implements DbOperations {
private Transaction transaction;
private final ConnectionWrapper connection;
SimpleConnection(final Connection connection, final Context context, final DbDialect dialect) {
this.connection = new ConnectionWrapper(connection, context, dialect);
}
/**
* Wrap an existing {@link Connection} with a {@link SimpleConnection}.
* <p>
* Note: Calling {@link #close()} will close the underlying connection.
*
* @param connection existing connection
* @param dialect database dialect
* @return wrapped connection
*/
public static SimpleConnection wrap(final Connection connection, final DbDialect dialect) {
return new SimpleConnection(connection, Context.builder().build(), dialect);
}
/**
* Start a new {@link Transaction} by disabling auto commit if necessary.
* <p>
* <em>Important:</em> The transaction must be committed or rolled back before
* the connection can be used again.
*
* @return new transaction
*/
public Transaction startTransaction() {
checkOperationAllowed();
transaction = Transaction.start(this.connection, tx -> {
if (this.transaction != tx) {
throw new IllegalStateException("Transaction not allowed to commit or rollback another transaction");
}
this.transaction = null;
});
return transaction;
}
private void checkOperationAllowed() {
if (transaction != null) {
throw new IllegalStateException("Operation not allowed on connection when transaction is active");
}
if (this.connection.isClosed()) {
throw new IllegalStateException("Operation not allowed on closed connection");
}
}
@Override
public int executeUpdate(final String sql) {
checkOperationAllowed();
return connection.executeUpdate(sql);
}
@Override
public void executeScript(final String sqlScript) {
checkOperationAllowed();
connection.executeScript(sqlScript);
}
@Override
public int executeUpdate(final String sql, final PreparedStatementSetter preparedStatementSetter) {
checkOperationAllowed();
return connection.executeUpdate(sql, preparedStatementSetter);
}
@Override
public SimpleResultSet<Row> query(final String sql) {
checkOperationAllowed();
return connection.query(sql);
}
@Override
public <T> SimpleResultSet<T> query(final String sql, final PreparedStatementSetter preparedStatementSetter,
final RowMapper<T> rowMapper) {
checkOperationAllowed();
return connection.query(sql, preparedStatementSetter, rowMapper);
}
@Override
public StatementBatchBuilder statementBatch() {
checkOperationAllowed();
return connection.statementBatch();
}
@Override
public PreparedStatementBatchBuilder preparedStatementBatch() {
checkOperationAllowed();
return connection.preparedStatementBatch();
}
@Override
public <T> RowPreparedStatementBatchBuilder<T> preparedStatementBatch(final Class<T> rowType) {
checkOperationAllowed();
return connection.rowPreparedStatementBatch();
}
/**
* Get database metadata.
*
* @return metadata
*/
public DbMetaData getMetaData() {
checkOperationAllowed();
return connection.getMetaData();
}
public Connection getOriginalConnection() {
checkOperationAllowed();
return connection.getOriginalConnection();
}
/**
* Close the underlying {@link Connection}.
*
* @see Connection#close()
*/
@Override
public void close() {
connection.close();
}
}