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.
com.landawn.abacus.core.Executant Maven / Gradle / Ivy
/*
* Copyright (c) 2015, Haiyang Li.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.landawn.abacus.core;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import com.landawn.abacus.DataSourceManager;
import com.landawn.abacus.DataSourceSelector;
import com.landawn.abacus.IsolationLevel;
import com.landawn.abacus.Transaction.Action;
import com.landawn.abacus.annotation.Internal;
import com.landawn.abacus.core.SQLTransaction.CreatedBy;
import com.landawn.abacus.core.command.Command;
import com.landawn.abacus.core.command.SQLOperationCommand;
import com.landawn.abacus.core.interpreter.Interpreter;
import com.landawn.abacus.core.interpreter.InterpreterProxy;
import com.landawn.abacus.core.interpreter.SQLInterpreterFactory;
import com.landawn.abacus.dataSource.SQLDataSource;
import com.landawn.abacus.exception.InvalidTransactionIdException;
import com.landawn.abacus.exception.UncheckedSQLException;
import com.landawn.abacus.logging.Logger;
import com.landawn.abacus.logging.LoggerFactory;
import com.landawn.abacus.type.Type;
import com.landawn.abacus.type.TypeFactory;
import com.landawn.abacus.util.ExceptionUtil;
import com.landawn.abacus.util.JdbcUtil;
import com.landawn.abacus.util.N;
import com.landawn.abacus.util.OperationType;
import com.landawn.abacus.util.Options;
import com.landawn.abacus.util.Options.Jdbc;
import com.landawn.abacus.util.SQLParser;
import com.landawn.abacus.util.WD;
// TODO: Auto-generated Javadoc
/**
*
* @author Haiyang Li
* @since 0.8
*/
@Internal
public class Executant {
private static final Logger logger = LoggerFactory.getLogger(Executant.class);
private static final String SELECT_COUNT = "SELECT count(*) ";
private final DataSourceManager _dsm;
private final DataSourceSelector _dss;
private final SQLDataSource _ds;
private final Interpreter _interpreter;
private final IsolationLevel _defaultIsolationLevel;
public Executant(DataSourceManager dsm) throws UncheckedSQLException {
this._dsm = dsm;
this._dss = dsm.getDataSourceSelector();
this._ds = (SQLDataSource) dsm.getPrimaryDataSource();
Connection conn = null;
try {
conn = _ds.getConnection();
DatabaseMetaData dmd = conn.getMetaData();
String proudctName = dmd.getDatabaseProductName();
String productVersion = dmd.getDatabaseProductVersion();
_interpreter = new InterpreterProxy(SQLInterpreterFactory.getInterpreter(proudctName, productVersion));
final IsolationLevel tmp = this._ds.getDefaultIsolationLevel();
_defaultIsolationLevel = tmp == IsolationLevel.DEFAULT ? IsolationLevel.valueOf(conn.getTransactionIsolation()) : tmp;
} catch (SQLException e) {
throw new UncheckedSQLException(ExceptionUtil.getMessage(e), e);
} finally {
closeConnection(_ds, conn, null);
}
}
/**
*
* @param command
* @param isAutoGeneratedKeys
* @param options
* @return
*/
public SQLResult executeUpdate(Command command, boolean isAutoGeneratedKeys, Map options) {
return internalExecuteUpdate(checkCmd(command), isAutoGeneratedKeys, options);
}
/**
*
* @param command
* @param options
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
public int executeCount(Command command, Map options) throws UncheckedSQLException {
SQLOperationCommand sqlCommand = checkCmd(command);
String querySQL = sqlCommand.getSql();
int fromIndex = SQLParser.indexWord(querySQL, WD.FROM, 6, false);
int toIndex = SQLParser.indexWord(querySQL, WD.OFFSET, fromIndex, false);
if (toIndex < 0) {
toIndex = SQLParser.indexWord(querySQL, WD.FOR_UPDATE, fromIndex, false);
}
toIndex = (toIndex < 0) ? querySQL.length() : toIndex;
String countQuerySQL = SELECT_COUNT + querySQL.substring(fromIndex, toIndex);
int resultSize = 0;
SQLResult queryResult = null;
try {
sqlCommand.setSql(countQuerySQL);
queryResult = internalExecuteQuery(sqlCommand, false, false, options);
if (queryResult.next()) {
resultSize = ((Number) queryResult.get(0)).intValue();
}
} catch (SQLException e) {
throw new UncheckedSQLException(e);
} finally {
sqlCommand.setSql(querySQL);
if (queryResult != null) {
queryResult.close();
}
}
return resultSize;
}
/**
*
* @param command
* @param options
* @return
*/
public SQLResult executeQuery(Command command, Map options) {
return internalExecuteQuery(checkCmd(command), false, false, options);
}
/**
* Execute query with handle.
*
* @param command
* @param options
* @return
*/
public SQLResult executeQueryWithHandle(Command command, Map options) {
return internalExecuteQuery(checkCmd(command), true, false, options);
}
/**
*
* @param isolationLevel
* @param options
* @return
*/
public String beginTransaction(final IsolationLevel isolationLevel, final Map options) {
N.checkArgNotNull(isolationLevel, "isolationLevel");
final boolean forUpdateOnly = EntityManagerUtil.isTransactionForUpdateOnly(options);
final String queryWithDataSource = EntityManagerUtil.getQueryWithDataSource(options);
final DataSource ds = N.isNullOrEmpty(queryWithDataSource) ? _ds : _dsm.getActiveDataSource(queryWithDataSource);
if (ds == null) {
throw new IllegalArgumentException("No active data source found by name: " + queryWithDataSource);
}
SQLTransaction tran = SQLTransaction.getTransaction(ds, CreatedBy.NEW_ENTITY_MANAGER);
if (tran == null) {
Connection conn = null;
boolean noException = false;
try {
conn = JdbcUtil.getConnection(ds);
tran = new SQLTransaction(ds, conn, isolationLevel == IsolationLevel.DEFAULT ? _defaultIsolationLevel : isolationLevel,
CreatedBy.NEW_ENTITY_MANAGER, true);
tran.incrementAndGetRef(isolationLevel, forUpdateOnly);
noException = true;
} catch (SQLException e) {
throw new UncheckedSQLException(e);
} finally {
if (noException == false) {
JdbcUtil.releaseConnection(conn, ds);
}
}
logger.info("Create a new SQLTransaction(id={})", tran.id());
SQLTransaction.putTransaction(tran);
} else {
logger.info("Reusing the existing SQLTransaction(id={})", tran.id());
tran.incrementAndGetRef(isolationLevel, forUpdateOnly);
}
return tran.id();
}
/**
* Gets the transaction.
*
* @param transactionId
* @return
*/
public SQLTransaction getTransaction(String transactionId) {
SQLTransaction tran = SQLTransaction.getTransaction(transactionId);
if (tran == null) {
throw new InvalidTransactionIdException("No transaction found with transaction id: " + transactionId);
}
return tran;
}
/**
*
* @param transactionId
* @param transactionAction
* @param options
*/
@SuppressWarnings("deprecation")
public void endTransaction(String transactionId, Action transactionAction, @SuppressWarnings("unused") Map options) {
final SQLTransaction tran = getTransaction(transactionId);
// Should never happen.
if (!(transactionAction == Action.COMMIT || transactionAction == Action.ROLLBACK)) {
throw new IllegalArgumentException("Unsupported transaction action[" + transactionAction + "]. ");
}
if (transactionAction == Action.COMMIT) {
tran.commit();
} else {
tran.rollback();
}
}
/**
* Gets the interpreter.
*
* @return
*/
public Interpreter getInterpreter() {
return _interpreter;
}
/**
* Internal execute update.
*
* @param sqlCommand
* @param isAutoGeneratedKeys
* @param options
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
SQLResult internalExecuteUpdate(SQLOperationCommand sqlCommand, boolean isAutoGeneratedKeys, Map options) throws UncheckedSQLException {
SQLDataSource ds = getDataSource(sqlCommand, options);
if (ds.isSqlLogEnable() && logger.isInfoEnabled()) {
logger.info(sqlCommand.getSql());
}
long startTime = System.currentTimeMillis();
long executionTime = 0;
int udpatedCount = 0;
List autoGeneratedKeys = null;
final PreparedStatement stmt = prepareStatement(ds, sqlCommand, isAutoGeneratedKeys, false, false, options);
ResultSet rs = null;
try {
if (sqlCommand.isBatch()) {
int[] results = stmt.executeBatch();
for (int result : results) {
udpatedCount += result;
}
} else {
udpatedCount = stmt.executeUpdate();
}
if (isAutoGeneratedKeys) {
try {
rs = stmt.getGeneratedKeys();
autoGeneratedKeys = new ArrayList<>(udpatedCount);
while (rs.next()) {
autoGeneratedKeys.add(JdbcUtil.getColumnValue(rs, 1));
}
} catch (SQLException e) {
logger.error("Failed to retrieve the auto-generated Ids", e);
}
}
} catch (SQLException e) {
throw new UncheckedSQLException(ExceptionUtil.getMessage(e) + ". [SQL]:" + sqlCommand.getSql(), e);
} finally {
executionTime = System.currentTimeMillis() - startTime;
if (ds.isPerfLog() && (executionTime > ds.getPerfLog()) && logger.isWarnEnabled()) {
logger.warn("[PERF] [" + (System.currentTimeMillis() - startTime) + "] " + sqlCommand.toString());
}
if (sqlCommand.isBatch()) {
try {
stmt.clearBatch();
} catch (SQLException e) {
logger.error("Failed to clear batch parameters", e);
}
}
closeResultSet(rs);
closeStatement(ds, stmt, options);
}
if (isAutoGeneratedKeys) {
return new SQLResult(this, sqlCommand, executionTime, udpatedCount, autoGeneratedKeys);
} else {
return new SQLResult(this, sqlCommand, executionTime, udpatedCount);
}
}
/**
* Internal execute query.
*
* @param sqlCommand
* @param queryWithHandle
* @param queryInUpdate
* @param options
* @return
*/
SQLResult internalExecuteQuery(SQLOperationCommand sqlCommand, boolean queryWithHandle, boolean queryInUpdate, Map options) {
SQLDataSource ds = getDataSource(sqlCommand, options);
if (ds.isSqlLogEnable() && logger.isInfoEnabled()) {
logger.info(sqlCommand.getSql());
}
options = EntityManagerUtil.copyOptions(options);
if (options.get(Jdbc.RESULT_SET_TYPE) == null) {
options.put(Jdbc.RESULT_SET_TYPE, ResultSet.TYPE_SCROLL_INSENSITIVE);
}
if (options.get(Jdbc.RESULT_SET_CONCURRENCY) == null) {
options.put(Jdbc.RESULT_SET_CONCURRENCY, ResultSet.CONCUR_READ_ONLY);
}
long startTime = System.currentTimeMillis();
long executionTime = 0;
final PreparedStatement stmt = prepareStatement(ds, sqlCommand, false, queryWithHandle, queryInUpdate, options);
ResultSet rs = null;
try {
rs = stmt.executeQuery();
} catch (SQLException e) {
closeResultSet(rs);
closeStatement(ds, stmt, options);
throw new UncheckedSQLException(ExceptionUtil.getMessage(e) + ". [SQL]:" + sqlCommand.getSql(), e);
} finally {
executionTime = System.currentTimeMillis() - startTime;
if (ds.isPerfLog() && (executionTime > ds.getPerfLog()) && logger.isWarnEnabled()) {
logger.warn("[PERF] [" + (System.currentTimeMillis() - startTime) + "] " + sqlCommand.toString());
}
}
if (queryWithHandle) {
return new HandledSQLResult(this, sqlCommand, options, ds, stmt, rs, executionTime);
} else {
return new SQLResult(this, sqlCommand, options, ds, stmt, rs, executionTime);
}
}
/**
* Gets the transaction.
*
* @param transactionId
* @param ds
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
private SQLTransaction getTransaction(String transactionId, SQLDataSource ds) throws UncheckedSQLException {
SQLTransaction tran = SQLTransaction.getTransaction(transactionId);
if (tran == null) {
throw new InvalidTransactionIdException("No transaction found with id: " + transactionId);
}
if (!ds.equals(tran.dataSource())) {
throw new IllegalStateException(
"Can't started mult-transaction between different data sources with transaction id: " + transactionId + "it's not supported yet");
}
return tran;
}
/**
* Select data source.
*
* @param sqlCommand
* @param options
* @return
*/
private SQLDataSource getDataSource(SQLOperationCommand sqlCommand, Map options) {
String entityName = sqlCommand.getEntityDef() == null ? null : sqlCommand.getEntityDef().getName();
SQLDataSource ds = null;
if (sqlCommand.isBatch()) {
ds = (SQLDataSource) _dss.select(_dsm, entityName, sqlCommand.getSql(), sqlCommand.getBatchParameters(), options);
} else {
ds = (SQLDataSource) _dss.select(_dsm, entityName, sqlCommand.getSql(), sqlCommand.getParameters(), options);
}
if (ds == null) {
throw new IllegalArgumentException("No data source selected for sql command: " + sqlCommand.toString());
}
return ds;
}
/**
* Gets the connection.
*
* @param ds
* @param sqlCommand
* @param queryWithHandle
* @param queryInUpdate
* @param options
* @return
*/
private Connection getConnection(SQLDataSource ds, SQLOperationCommand sqlCommand, boolean queryWithHandle, boolean queryInUpdate,
Map options) {
boolean isQuery = (sqlCommand != null) && (sqlCommand.getOperationType() == OperationType.QUERY);
boolean isInTransaction = EntityManagerUtil.isInTransaction(options);
if (queryWithHandle) {
if (isInTransaction) {
throw new IllegalArgumentException("Can't query with 'resultHandle' in transaction.");
}
return ds.getPersistentConnection();
} else if (isInTransaction) {
final SQLTransaction tran = getTransaction(EntityManagerUtil.getTransactionId(options), ds);
if (isQuery == false || tran.isForUpdateOnly() == false) {
return getTransaction(options.get(Options.TRANSACTION_ID).toString(), ds).connection();
}
}
if (isQuery && (ds.isQueryWithReadOnlyConnectionByDefault() || EntityManagerUtil.isQueryWithReadOnlyConection(options))
&& !(EntityManagerUtil.notQueryWithReadOnlyConection(options) || queryInUpdate)) {
return ds.getReadOnlyConnection();
} else {
return JdbcUtil.getConnection(ds);
}
}
/**
*
* @param ds
* @param sqlCommand
* @param isAutoGeneratedKeys
* @param queryWithHandle
* @param queryInUpdate
* @param options
* @return
* @throws UncheckedSQLException the unchecked SQL exception
*/
private PreparedStatement prepareStatement(SQLDataSource ds, SQLOperationCommand sqlCommand, boolean isAutoGeneratedKeys, boolean queryWithHandle,
boolean queryInUpdate, Map options) throws UncheckedSQLException {
String entityName = sqlCommand.getEntityDef() == null ? null : sqlCommand.getEntityDef().getName();
String sql = sqlCommand.getSql();
if (sqlCommand.isBatch()) {
sql = ds.getSliceSelector().select(entityName, sql, sqlCommand.getBatchParameters(), options);
} else {
sql = ds.getSliceSelector().select(entityName, sql, sqlCommand.getParameters(), options);
}
int timeout = -1;
if ((options != null) && (options.get(Jdbc.QUERY_TIMEOUT) != null)) {
timeout = ((Number) options.get(Jdbc.QUERY_TIMEOUT)).intValue();
if (timeout < 0) {
throw new IllegalArgumentException("Jdbc timeout[" + timeout + "] must not less than zero.");
}
}
int maxRows = -1;
if ((options != null) && (options.get(Jdbc.MAX_ROWS) != null)) {
maxRows = (Integer) options.get(Jdbc.MAX_ROWS);
if (maxRows < 0) {
throw new IllegalArgumentException("'maxRows[" + maxRows + "] must not less than zero.");
}
}
int maxFieldSize = -1;
if ((options != null) && (options.get(Jdbc.MAX_FIELD_SIZE) != null)) {
maxFieldSize = (Integer) options.get(Jdbc.MAX_FIELD_SIZE);
if (maxFieldSize < 0) {
throw new IllegalArgumentException("maxFieldSize[" + maxFieldSize + "] must not less than zero.");
}
}
int fetchSize = -1;
if ((options != null) && (options.get(Jdbc.FETCH_SIZE) != null)) {
fetchSize = (Integer) options.get(Jdbc.FETCH_SIZE);
if (fetchSize < 0) {
throw new IllegalArgumentException("fetchSize[" + fetchSize + "] must not less than zero.");
}
}
int fetchDirection = -1;
if ((options != null) && (options.get(Jdbc.FETCH_DIRECTION) != null)) {
fetchDirection = (Integer) options.get(Jdbc.FETCH_DIRECTION);
if (fetchDirection < 0) {
throw new IllegalArgumentException("fetchDirection[" + fetchDirection + "] must not less than zero.");
}
}
int resultSetType = -1;
if ((options != null) && (options.get(Jdbc.RESULT_SET_TYPE) != null)) {
resultSetType = (Integer) options.get(Jdbc.RESULT_SET_TYPE);
if (resultSetType < 0) {
throw new IllegalArgumentException("resultSetType[" + resultSetType + "] must not less than zero.");
}
}
int resultSetConcurrency = -1;
if ((options != null) && (options.get(Jdbc.RESULT_SET_CONCURRENCY) != null)) {
resultSetConcurrency = (Integer) options.get(Jdbc.RESULT_SET_CONCURRENCY);
if (resultSetConcurrency < 0) {
throw new IllegalArgumentException("resultSetConcurrency[" + resultSetConcurrency + "] must not less than zero. ");
}
}
int resultSetHoldability = -1;
if ((options != null) && (options.get(Jdbc.RESULT_SET_HOLDABILITY) != null)) {
resultSetHoldability = (Integer) options.get(Jdbc.RESULT_SET_HOLDABILITY);
if (resultSetHoldability < 0) {
throw new IllegalArgumentException("resultSetHoldability[" + resultSetHoldability + "] must not less than zero.");
}
}
if (!(((resultSetType > -1) && (resultSetConcurrency > -1) && (resultSetHoldability > -1))
|| ((resultSetType > -1) && (resultSetConcurrency > -1) && (resultSetHoldability < 0))
|| ((resultSetType < 0) && (resultSetConcurrency < 0) && (resultSetHoldability < 0)))) {
throw new IllegalArgumentException("resultSetHoldability=" + resultSetHoldability + ". resultSetType=" + resultSetType + ". resultSetConcurrency="
+ resultSetConcurrency + ".");
}
final Connection conn = getConnection(ds, sqlCommand, queryWithHandle, queryInUpdate, options);
PreparedStatement stmt = null;
boolean noException = false;
try {
if ((resultSetType != -1) || (resultSetConcurrency != -1) || (resultSetHoldability != -1)) {
resultSetType = (resultSetType == -1) ? ResultSet.TYPE_FORWARD_ONLY : resultSetType;
resultSetConcurrency = (resultSetConcurrency == -1) ? ResultSet.CONCUR_READ_ONLY : resultSetConcurrency;
if (resultSetHoldability != -1) {
stmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability);
} else {
stmt = conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
}
} else {
if (isAutoGeneratedKeys) {
stmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
} else {
stmt = conn.prepareStatement(sql);
}
}
if (timeout != -1) {
stmt.setQueryTimeout(timeout);
}
if (maxRows != -1) {
stmt.setMaxRows(maxRows);
}
if (maxFieldSize != -1) {
stmt.setMaxFieldSize(maxFieldSize);
}
if (fetchSize != -1) {
stmt.setFetchSize(fetchSize);
}
if (fetchDirection != -1) {
stmt.setFetchDirection(fetchDirection);
}
setParameterValue(sqlCommand, stmt);
noException = true;
} catch (SQLException e) {
throw new UncheckedSQLException(ExceptionUtil.getMessage(e) + ". [SQL]:" + sqlCommand.getSql(), e);
} finally {
if (!noException) {
closeStatement(ds, stmt, options);
}
}
return stmt;
}
/**
* Sets the parameter value.
*
* @param sqlCommand
* @param stmt
* @throws SQLException the SQL exception
*/
private void setParameterValue(SQLOperationCommand sqlCommand, PreparedStatement stmt) throws SQLException {
Type type = null;
Object parameterValue = null;
if (sqlCommand.isBatch()) {
List parametersList = sqlCommand.getBatchParameters();
for (Object[] parameters : parametersList) {
for (int parameterIndex = 0, len = parameters.length; parameterIndex < len; parameterIndex++) {
type = sqlCommand.getParameterType(parameterIndex);
parameterValue = parameters[parameterIndex];
if (type == null) {
stmt.setObject(parameterIndex + 1, parameterValue);
} else {
type.set(stmt, parameterIndex + 1, parameterValue);
}
}
stmt.addBatch();
}
} else {
for (int parameterIndex = 0, len = sqlCommand.getParameterCount(); parameterIndex < len; parameterIndex++) {
type = sqlCommand.getParameterType(parameterIndex);
parameterValue = sqlCommand.getParameter(parameterIndex);
if (type == null) {
stmt.setObject(parameterIndex + 1, parameterValue);
} else {
try {
type.set(stmt, parameterIndex + 1, parameterValue);
} catch (ClassCastException e) {
// ignore
if (logger.isWarnEnabled()) {
logger.warn("Failed to set parameter value(" + parameterValue + ") due to error: " + ExceptionUtil.getMessage(e)
+ ". Try to convert value and reset.");
}
Type srcType = TypeFactory.getType(parameterValue.getClass());
type.set(stmt, parameterIndex + 1, type.valueOf(srcType.stringOf(parameterValue)));
} catch (Exception e) {
// ignore
if (logger.isWarnEnabled()) {
logger.warn("Failed to set parameter value(" + parameterValue + ") due to error: " + ExceptionUtil.getMessage(e)
+ ". Try to reset it by setObject(...).");
}
stmt.setObject(parameterIndex + 1, parameterValue);
}
}
}
}
}
/**
* Close result set.
*
* @param rs
*/
void closeResultSet(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// ignore;
logger.error("Failed to close ResultSet", e);
}
}
}
/**
*
* @param ds
* @param stmt
* @param options
*/
void closeStatement(SQLDataSource ds, Statement stmt, Map options) {
if (stmt != null) {
Connection conn = null;
try {
conn = stmt.getConnection();
} catch (SQLException e) {
// ignore;
logger.error("Failed to stmt.getConnection() in close action", e);
}
try {
stmt.close();
} catch (SQLException e) {
// ignore;
logger.error("Failed to close Statement", e);
}
if (conn != null) {
closeConnection(ds, conn, options);
}
}
}
/**
*
* @param ds
* @param conn
* @param options
* @return true, if successful
*/
boolean closeConnection(SQLDataSource ds, Connection conn, Map options) {
if ((conn != null) && !ds.isPersistentConnection(conn) && !EntityManagerUtil.isInTransaction(options)) {
JdbcUtil.releaseConnection(conn, ds);
return true;
}
return false;
}
/**
*
* @param command
* @return
*/
private static SQLOperationCommand checkCmd(Command command) {
if (command instanceof SQLOperationCommand) {
return (SQLOperationCommand) command;
} else {
throw new IllegalArgumentException("The sql executant only recognize sql operation command, can't recognize cmd [" + command.toString() + "]. ");
}
}
/**
* The Class HandledSQLResult.
*/
private static class HandledSQLResult extends SQLResult {
/**
* Instantiates a new handled SQL result.
*
* @param executant
* @param sqlCommand
* @param options
* @param ds
* @param stmt
* @param rs
* @param executionTime
*/
public HandledSQLResult(Executant executant, SQLOperationCommand sqlCommand, Map options, SQLDataSource ds, Statement stmt,
ResultSet rs, long executionTime) {
super(executant, sqlCommand, options, ds, stmt, rs, executionTime);
}
/**
* Close.
*/
@Override
public void close() {
if (isClosed()) {
return;
}
synchronized (this) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
// ignore
logger.error("Failed to close statement when close ResultHandle", e);
}
}
}
}
}
}