/* * JBoss, Home of Professional Open Source. * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. Some portions may be licensed * to Red Hat, Inc. under one or more contributor license agreements. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA. */ package org.teiid.translator.jdbc; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.util.List; import org.teiid.language.Argument; import org.teiid.language.Command; import org.teiid.language.Literal; import org.teiid.language.Parameter; import org.teiid.logging.LogConstants; import org.teiid.logging.LogManager; import org.teiid.logging.MessageLevel; import org.teiid.translator.Execution; import org.teiid.translator.ExecutionContext; import org.teiid.translator.TranslatorException; /** */ public abstract class JDBCBaseExecution implements Execution { // =========================================================================================================================== // Fields // =========================================================================================================================== // Passed to constructor protected Connection connection; protected ExecutionContext context; protected JDBCExecutionFactory executionFactory; protected Command command; // Derived from properties protected boolean trimString; protected int fetchSize; // Set during execution protected volatile Statement statement; private volatile boolean canceled; // =========================================================================================================================== // Constructors // =========================================================================================================================== protected JDBCBaseExecution(Command command, Connection connection, ExecutionContext context, JDBCExecutionFactory jef) { this.connection = connection; this.context = context; this.executionFactory = jef; trimString = jef.isTrimStrings(); fetchSize = context.getBatchSize(); this.command = command; } /** * Bind the values in the TranslatedCommand to the PreparedStatement */ protected void bind(PreparedStatement stmt, List<?> params, List<?> batchValues) throws SQLException { for (int i = 0; i< params.size(); i++) { Object paramValue = params.get(i); Object value = null; Class<?> paramType = null; if (paramValue instanceof Literal) { Literal litParam = (Literal)paramValue; value = litParam.getValue(); paramType = litParam.getType(); } else if (paramValue instanceof Argument) { Argument arg = (Argument)paramValue; value = ((Literal)arg.getExpression()).getValue(); paramType = arg.getType(); } else { Parameter param = (Parameter)paramValue; if (batchValues == null) { throw new AssertionError("Expected batchValues when using a Parameter"); //$NON-NLS-1$ } value = batchValues.get(param.getValueIndex()); paramType = param.getType(); } this.executionFactory.bindValue(stmt, value, paramType, i+1); } if (batchValues != null) { stmt.addBatch(); } } // =========================================================================================================================== // Methods // =========================================================================================================================== protected TranslatedCommand translateCommand(Command command) throws TranslatorException { TranslatedCommand translatedCommand = new TranslatedCommand(context, this.executionFactory); translatedCommand.translateCommand(command); if (translatedCommand.getSql() != null && LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL)) { LogManager.logDetail(LogConstants.CTX_CONNECTOR, "Source-specific command: " + translatedCommand.getSql()); //$NON-NLS-1$ } context.logCommand(translatedCommand.getSql()); return translatedCommand; } public void close() { try { if (statement != null) { if (canceled) { try { this.executionFactory.intializeConnectionAfterCancel(connection); } catch (SQLException e) { LogManager.logDetail(LogConstants.CTX_CONNECTOR, e, "Exception closing"); //$NON-NLS-1$ } } statement.close(); } } catch (SQLException e) { LogManager.logDetail(LogConstants.CTX_CONNECTOR, e, "Exception closing"); //$NON-NLS-1$ } } public void cancel() throws TranslatorException { // if both the DBMS and driver support aborting an SQL try { Statement s = this.statement; if (s != null) { s.cancel(); this.canceled = true; } } catch (SQLException e) { // Defect 16187 - DataDirect does not support the cancel() method for // Statement.cancel() for DB2 and Informix. Here we are tolerant // of these and other JDBC drivers that do not support the cancel() operation. } } protected void setSizeContraints(Statement statement) { try { executionFactory.setFetchSize(command, context, statement, fetchSize); } catch (SQLException e) { if (LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL)) { LogManager.logDetail(LogConstants.CTX_CONNECTOR, context.getRequestId(), " could not set fetch size: ", fetchSize); //$NON-NLS-1$ } } } protected Statement getStatement() throws SQLException { if (statement != null) { statement.close(); statement = null; } statement = connection.createStatement(); setSizeContraints(statement); return statement; } protected CallableStatement getCallableStatement(String sql) throws SQLException { if (statement != null) { statement.close(); statement = null; } statement = connection.prepareCall(sql); setSizeContraints(statement); return (CallableStatement)statement; } protected PreparedStatement getPreparedStatement(String sql) throws SQLException { if (statement != null) { statement.close(); statement = null; } statement = connection.prepareStatement(sql); setSizeContraints(statement); return (PreparedStatement)statement; } /** * Returns the JDBC connection used by the execution object. * * @return Returns the connection. * @since 4.1.1 */ public Connection getConnection() { return this.connection; } public void addStatementWarnings() throws SQLException { SQLWarning warning = this.statement.getWarnings(); if (warning != null) { context.addWarning(warning); if (LogManager.isMessageToBeRecorded(LogConstants.CTX_CONNECTOR, MessageLevel.DETAIL)) { while (warning != null) { LogManager.logDetail(LogConstants.CTX_CONNECTOR, context.getRequestId() + " Warning: ", warning); //$NON-NLS-1$ warning = warning.getNextWarning(); } } } this.statement.clearWarnings(); } }