com.jpattern.orm.session.datasource.DataSourceConnection Maven / Gradle / Ivy
package com.jpattern.orm.session.datasource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jpattern.orm.exception.OrmException;
import com.jpattern.orm.exception.OrmRollbackException;
public class DataSourceConnection implements IConnection {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private ConnectionWrapper connectionWrapper;
private List connectionCallers = new ArrayList();
private boolean rollbackOnly = false;
private boolean readOnly = false;
private boolean valid = true;
public DataSourceConnection(final DataSource dataSource, final boolean readOnly) {
this.connectionWrapper = new ConnectionWrapper(dataSource);
this.setReadOnly(readOnly);
}
@Override
public void setTransactionIsolation(final int transactionIsolation) throws OrmException {
try {
this.connectionWrapper.setTransactionIsolation(transactionIsolation);
} catch (SQLException e) {
throw new OrmException(e);
}
}
@Override
public boolean isClosed() throws OrmException {
try {
return this.connectionWrapper.isClosed();
} catch (SQLException e) {
throw new OrmException(e);
}
}
@Override
public void rollback() throws OrmException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("rollback called");
}
if ((this.connectionCallers.size()==1) && !this.isReadOnly()) {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("performing rollback");
}
this.connectionWrapper.rollback();
} catch (SQLException e) {
throw new OrmException(e);
}
}
}
@Override
public void commit() throws OrmException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("commit called");
}
if ((this.connectionCallers.size()==1) && !this.isReadOnly()) {
if (this.rollbackOnly) {
this.rollback();
throw new OrmRollbackException("Transaction rolled back because it has been marked as rollback-only");
}
else {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("performing commit");
}
this.connectionWrapper.commit();
} catch (SQLException e) {
throw new OrmException(e);
}
}
}
}
@Override
public PreparedStatement prepareStatement(final String sql) throws OrmException {
try {
return this.connectionWrapper.prepareStatement(sql);
} catch (SQLException e) {
throw new OrmException(e);
}
}
@Override
public PreparedStatement prepareStatement(final String sql, final String[] generatedColumnNames) throws OrmException {
try {
return this.connectionWrapper.prepareStatement(sql, generatedColumnNames) ;
} catch (SQLException e) {
throw new OrmException(e);
}
}
@Override
public IStatement createStatement() throws OrmException {
try {
return new StatementWrapper(this.connectionWrapper.createStatement() , this);
} catch (SQLException e) {
throw new OrmException(e);
}
}
@Override
public void addCaller(final IConnectionCaller connectionCaller) throws OrmException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Caller " + connectionCaller + " registered");
}
this.connectionCallers.add(connectionCaller);
}
@Override
public void close(final IConnectionCaller connectionCaller) throws OrmException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Caller " + connectionCaller + " called a close on transaction");
}
this.connectionCallers.remove(connectionCaller);
if (this.connectionCallers.isEmpty()) {
try {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Closing SQL connection");
}
this.connectionWrapper.close();
this.valid = false;
} catch (SQLException e) {
throw new OrmException(e);
}
}
}
@Override
public void setRollbackOnly() throws OrmException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Transaction sets as a rollbackOnly");
}
this.rollbackOnly = true;
}
@Override
public void setReadOnly(final boolean readOnly) throws OrmException {
this.readOnly = readOnly;
}
@Override
public boolean isValid() throws OrmException {
return this.valid;
}
public boolean isReadOnly() {
return this.readOnly;
}
class ConnectionWrapper {
private java.sql.Connection connection;
private final DataSource dataSource;
private Savepoint savepoint;
ConnectionWrapper(final DataSource dataSource) {
this.dataSource = dataSource;
}
public void setTransactionIsolation(final int transactionIsolation) throws SQLException {
this.validateConnection();
this.connection.setTransactionIsolation(transactionIsolation);
}
public void rollback() throws SQLException {
if (this.connection!=null) {
if (this.savepoint==null) {
this.connection.rollback();
} else {
this.connection.rollback(this.savepoint);
}
}
}
public void rollback(final Savepoint savepoint) throws SQLException {
if (this.connection!=null) {
this.connection.rollback(savepoint);
}
}
public void commit() throws SQLException {
if (this.connection!=null) {
this.connection.commit();
}
}
public Statement createStatement() throws SQLException {
this.validateConnection();
return this.connection.createStatement();
}
public PreparedStatement prepareStatement(final String sql) throws SQLException {
this.validateConnection();
return this.connection.prepareStatement(sql);
}
public PreparedStatement prepareStatement(final String sql, final String[] generatedColumnNames) throws SQLException {
this.validateConnection();
return this.connection.prepareStatement(sql, generatedColumnNames);
}
public void close() throws SQLException {
if (this.connection!=null) {
this.connection.close();
}
}
public boolean isClosed() throws SQLException {
if (this.connection!=null) {
return this.connection.isClosed();
}
return true;
}
private void validateConnection() throws SQLException {
if (!DataSourceConnection.this.isValid()) {
throw new OrmException("Not possible to open a new java.sql.Connection");
}
if (this.isClosed()) {
if (DataSourceConnection.this.logger.isDebugEnabled()) {
DataSourceConnection.this.logger.debug("Sql connection is null or closed. Opening a new sql connection.");
}
Connection sqlConn = this.dataSource.getConnection();
if (!DataSourceConnection.this.isReadOnly()) {
this.savepoint = sqlConn.setSavepoint();
}
this.connection = sqlConn;
}
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy