All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.kawanfw.sql.jdbc.PreparedStatementHttp Maven / Gradle / Ivy

/*
 * This file is part of AceQL. 
 * AceQL: Remote JDBC access over HTTP.                                     
 * Copyright (C) 2015,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                                
 *                                                                               
 * AceQL 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.            
 *                                                                               
 * AceQL 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
 *
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.kawanfw.sql.jdbc;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.BatchUpdateException;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLXML;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.kawanfw.commons.util.ClientLogger;
import org.kawanfw.commons.util.FrameworkDebug;
import org.kawanfw.commons.util.FrameworkFileUtil;
import org.kawanfw.commons.util.HtmlConverter;
import org.kawanfw.commons.util.KeepTempFilePolicyParms;
import org.kawanfw.commons.util.Tag;
import org.kawanfw.file.api.util.client.FilesTransferWithProgress;
import org.kawanfw.sql.jdbc.http.JdbcHttpBatchTransfer;
import org.kawanfw.sql.jdbc.http.JdbcHttpExecuteRawTransfer;
import org.kawanfw.sql.jdbc.http.JdbcHttpStatementTransfer;
import org.kawanfw.sql.jdbc.http.JdbcHttpTransferUtil;
import org.kawanfw.sql.jdbc.util.ParametersUtil;
import org.kawanfw.sql.jdbc.util.TransportAsciiStream;
import org.kawanfw.sql.jdbc.util.TransportInputStream;
import org.kawanfw.sql.jdbc.util.TransportReader;
import org.kawanfw.sql.json.IntArrayTransport;
import org.kawanfw.sql.json.StatementHolder;
import org.kawanfw.sql.transport.TransportConverter;
import org.kawanfw.sql.util.FileNameFromBlobBuilder;

/**
 * Creates and handle a Prepared Statement Http.
 */

public class PreparedStatementHttp extends StatementHttp implements
	PreparedStatement {

    /** Debug flag */
    private static boolean DEBUG = FrameworkDebug
	    .isSet(PreparedStatementHttp.class);

    /**
     * The holder that contains the sql order and the list if (parameter type,
     * parameter value ) for prepared statements
     **/
    private StatementHolder statementHolder = null;

    /** The statement to execute */
    private String sql = null;

    /**
     * The update count returned by PreparedStatementHttp.getUpdateCount() after
     * an execute()
     */
    private int updateCount = 0;

    /**
     * The list of local files to uplaod and delete (in fire and forget mode) at
     * end of prepared statement.
     */
    protected List localFilesStatement = null;

    /**
     * The list of remote uploaded files delete (in fire and forget mode) at end
     * of prepared statement.
     */
    protected List remoteFilesStatement = null;

    // /**
    // * The list of input streams to delete (in fire and forget mode) at end of
    // * prepared statement
    // */
    // protected List localInputStreams = null;
    //
    //
    // /** The length of each InputStream */
    // protected List localInputStreamLengths = null;

    /**
     * Constructor
     * 
     * @param connectionHttp
     *            The Http Connection
     * @param sql
     *            the sql statement to use
     * @param resultSetType
     *            The result set type
     * @param resultSetConcurrency
     *            The result set concurrency
     * @param resultSetHoldability
     *            The result set holdability
     * @throws SQLException
     */
    public PreparedStatementHttp(ConnectionHttp connectionHttp, String sql,
	    int resultSetType, int resultSetConcurrency,
	    int resultSetHoldability) throws SQLException {

	super(connectionHttp, resultSetType, resultSetConcurrency,
		resultSetHoldability);

	if (sql == null) {
	    throw new SQLException("sql order is null!");
	}

	this.sql = sql.trim();

	statementHolder = new StatementHolder(sql, resultSetType,
		resultSetConcurrency, resultSetHoldability);
	statementHolder.setPreparedStatement(true);
	statementHolder.setHtmlEncodingOn(connectionHttp.isHtmlEncodingOn());

	localFilesStatement = new Vector();
	remoteFilesStatement = new Vector();
	// localInputStreams = new Vector();
	// localInputStreamLengths = new Vector();
    }

    /**
     * Constructor for auto-generated keys
     * 
     * @param connectionHttp
     *            The Http Connection
     * @param sql
     *            the sql statement to use
     * @param autoGeneratedKeys
     *            a flag indicating whether auto-generated keys should be
     *            returned; one of Statement.RETURN_GENERATED_KEYS
     *            or Statement.NO_GENERATED_KEYS
     * 
     * @throws SQLException
     */
    public PreparedStatementHttp(ConnectionHttp connectionHttp, String sql,
	    int autoGeneratedKeys) throws SQLException {

	super(connectionHttp, ResultSet.TYPE_FORWARD_ONLY,
		ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

	if (sql == null) {
	    throw new SQLException("sql order is null!");
	}

	this.sql = sql.trim();

	statementHolder = new StatementHolder(sql, autoGeneratedKeys);
	statementHolder.setPreparedStatement(true);
	statementHolder.setHtmlEncodingOn(connectionHttp.isHtmlEncodingOn());

	localFilesStatement = new Vector();
	remoteFilesStatement = new Vector();
	// localInputStreams = new Vector();
	// localInputStreamLengths = new Vector();

    }

    /**
     * Constructor for auto-generated keys
     * 
     * @param connectionHttp
     *            The Http Connection
     * @param sql
     *            the sql statement to use
     * @param columnIndexes
     *            an array of column indexes indicating the columns that should
     *            be returned from the inserted row or rows
     * 
     * @throws SQLException
     */

    public PreparedStatementHttp(ConnectionHttp connectionHttp, String sql,
	    int[] columnIndexes) throws SQLException {
	super(connectionHttp, ResultSet.TYPE_FORWARD_ONLY,
		ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

	if (sql == null) {
	    throw new SQLException("sql order is null!");
	}

	this.sql = sql.trim();

	statementHolder = new StatementHolder(sql, columnIndexes);
	statementHolder.setPreparedStatement(true);
	statementHolder.setHtmlEncodingOn(connectionHttp.isHtmlEncodingOn());

	localFilesStatement = new Vector();
	remoteFilesStatement = new Vector();
    }

    /**
     * Constructor for auto-generated keys
     * 
     * @param connectionHttp
     *            The Http Connection
     * @param sql
     *            the sql statement to use
     * @param columnNames
     *            an array of column names indicating the columns that should be
     *            returned from the inserted row or rows
     * 
     * @throws SQLException
     */

    public PreparedStatementHttp(ConnectionHttp connectionHttp, String sql,
	    String[] columnNames) throws SQLException {
	super(connectionHttp, ResultSet.TYPE_FORWARD_ONLY,
		ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT);

	if (sql == null) {
	    throw new SQLException("sql order is null!");
	}

	this.sql = sql.trim();

	statementHolder = new StatementHolder(sql, columnNames);
	statementHolder.setPreparedStatement(true);
	statementHolder.setHtmlEncodingOn(connectionHttp.isHtmlEncodingOn());

	localFilesStatement = new Vector();
	remoteFilesStatement = new Vector();
    }

    /**
     * @throws SQLException
     * @see java.sql.Statement#close()
     */
    @Override
    public void close() throws SQLException {

	super.close();
	statementHolder = null;

	deleteLocalContainers();

    }

    /**
     * Executes the SQL query in this PreparedStatement object and
     * returns the ResultSet object generated by the query.
     * 
     * @return a ResultSet object that contains the data produced
     *         by the query; never null
     * @exception SQLException
     *                if a database access error occurs or the SQL statement
     *                does not return a ResultSet object
     */
    @Override
    public ResultSet executeQuery() throws SQLException {

	testIfClosed();

	if (connectionHttp.isStatelessMode()) {
	    if (!connectionHttp.getAutoCommit()) {
		throw new IllegalStateException(
			Tag.PRODUCT
				+ "executeQuery() can\'t be executed when auto commit is off.");
	    }

	}

	// Check that all parameters values are set
	ParametersUtil.checkParameters(statementHolder);

	statementHolder.setPreparedStatement(true);
	statementHolder.setExecuteUpdate(false);
	statementHolder.setJoinResultSetMetaData(connectionHttp
		.isJoinResultSetMetaData());

	statementHolder.setFetchSize(fetchSize);
	statementHolder.setMaxRows(maxRows);
	statementHolder.setQueryTimeout(queryTimeout);
	statementHolder.setEscapeProcessing(escapeProcessingInt);

	// Send unique order to Server to SQL Executor
	JdbcHttpStatementTransfer jdbcHttpStatementTransfer = new JdbcHttpStatementTransfer(
		connectionHttp, connectionHttp.getAuthenticationToken());

	File receiveFile = jdbcHttpStatementTransfer
		.getFileFromExecuteQueryOnServer(statementHolder);
	debug("getFileFromexecuteOnServer() : " + receiveFile);

	ResultSet rs = new ResultSetHttp(connectionHttp, statementHolder, this,
		receiveFile);
	return rs;
    }

    /**
     * Get the total length of the files to upload
     * 
     * @return the total length of the files to upload
     */
    private long getLocalTotalLength() {
	long totalLength = 0;
	for (File localFileStatement : localFilesStatement) {
	    totalLength += localFileStatement.length();
	}

	// for (Long localLength : localInputStreamLengths) {
	// totalLength += localLength;
	// }

	return totalLength;
    }

    /**
     * Upload all the blob parameters
     */
    private void uploadBlobParameters() throws SQLException {

	try {

	    // reinit progress
	    connectionHttp.getProgress().set(0);

	    long totalLength = getLocalTotalLength();

	    // Upload local objects
	    FilesTransferWithProgress filesTransferWithProgress = new FilesTransferWithProgress(
		    connectionHttp.getRemoteSession(),
		    connectionHttp.getProgress(), connectionHttp.getCancelled());

	    // 1) Upoad files
	    if (!localFilesStatement.isEmpty()) {

		List filesUnmodifiableList = Collections
			.unmodifiableList(localFilesStatement);

		for (int i = filesUnmodifiableList.size() - 1; i > -1; i--) {
		    // Do the upload
		    debug("uploading file: " + filesUnmodifiableList.get(i));
		    filesTransferWithProgress.upload(
			    localFilesStatement.get(i),
			    remoteFilesStatement.get(i), totalLength);
		    FileUtils.deleteQuietly(filesUnmodifiableList.get(i));
		    localFilesStatement.remove(i);
		}

	    }

	    // // 2) upload InputStreams
	    // if (!localInputStreams.isEmpty()) {
	    //
	    // //debug("connectionHttp.getProgress(): " +
	    // connectionHttp.getProgress());
	    // //debug("localInputStreams.size()    : " +
	    // localInputStreams.size());
	    // //debug("localInputStreamLengths     : " +
	    // localInputStreamLengths);
	    //
	    // filesTransferWithProgress.upload(localInputStreams,
	    // localInputStreamLengths, remoteFilesStatement,
	    // totalLength);
	    // }

	} catch (Exception e) {
	    JdbcHttpTransferUtil.wrapExceptionAsSQLException(e);
	} finally {
	    // NO! We want to repeat the uploads, so stay at 99
	    // connectionHttp.getProgress().set(100);
	    // deleteLocalContainers();
	}

    }

    /**
     * Delete local files
     */
    private void deleteLocalContainers() {
	if (!KeepTempFilePolicyParms.KEEP_TEMP_FILE && !DEBUG) {
	    if (localFilesStatement != null) {
		for (File localFileStatement : localFilesStatement) {
		    localFileStatement.delete();
		}
	    }
	}
    }

    /**
     * Executes the SQL statement in this PreparedStatement object,
     * which must be an SQL INSERT, UPDATE or
     * DELETE statement; or an SQL statement that returns nothing,
     * such as a DDL statement.
     * 
     * @return either (1) the row count for INSERT,
     *         UPDATE, or DELETE statements or (2) 0
     *         for SQL statements that return nothing
     * @exception SQLException
     *                if a database access error occurs or the SQL statement
     *                returns a ResultSet object
     */
    @Override
    public synchronized int executeUpdate() throws SQLException {
	testIfClosed();

	lastExecuteIsRaw = false;

	// Check that all parameters values are set
	ParametersUtil.checkParameters(statementHolder);

	statementHolder.setPreparedStatement(true);
	statementHolder.setExecuteUpdate(true);

	int rc = 0;

	// Safety reset of list if we are in statefull mode
	// For method to be idempotent
	if (!connectionHttp.isStatelessMode()) {
	    connectionHttp.resetStatementHolderList();
	}

	// Add the statement to the statement list
	connectionHttp.addStatementHolder(statementHolder);

	// Execute for statefull mode
	if (!connectionHttp.isStatelessMode()) {
	    uploadBlobParameters();
	}

	// 25/04/14 15:20 - HACK NDP - There were no parenthesis
	if ((connectionHttp.isStatelessMode() && connectionHttp.getAutoCommit())
		|| !connectionHttp.isStatelessMode()) {
	    try {

		debug("before getStringFromExecuteUpdateListOnServer()");
		// Send order to Server to SQL Executor
		connectionHttp.receiveFromExecuteUpdate = connectionHttp
			.getStringFromExecuteUpdateListOnServer();
		debug("after getStringFromExecuteUpdateListOnServer()");

		connectionHttp.testIfUploadInterrupted();

		BufferedReader bufferedReader = new BufferedReader(
			new StringReader(
				connectionHttp.receiveFromExecuteUpdate));
		String line1 = null;
		try {
		    line1 = bufferedReader.readLine();
		} catch (IOException e1) {
		    throw new SQLException(e1);
		}

		connectionHttp.testIfUploadInterrupted();

		try {
		    rc = Integer.parseInt(line1);
		} catch (NumberFormatException e) {
		    throw new SQLException(Tag.PRODUCT_PRODUCT_FAIL
			    + e.getMessage(),
			    new IOException(e.getMessage(), e));
		}
	    } finally {
		connectionHttp.resetStatementHolderList(); // Safety reset of
							   // list

	    }
	}

	return rc;
    }

    /**
     * Executes the given SQL statement, which may return multiple results. In
     * some (uncommon) situations, a single SQL statement may return multiple
     * result sets and/or update counts. Normally you can ignore this unless you
     * are (1) executing a stored procedure that you know may return multiple
     * results or (2) you are dynamically executing an unknown SQL string.
     * 

* The execute method executes an SQL statement and indicates * the form of the first result. You must then use the methods * getResultSet or getUpdateCount to retrieve the * result, and getMoreResults to move to any subsequent * result(s). * * @param sql * any SQL statement * @return true if the first result is a ResultSet * object; false if it is an update count or there are * no results * @exception SQLException * if a database access error occurs * @see #getResultSet * @see #getUpdateCount * @see #getMoreResults */ @Override public boolean execute() throws SQLException { testIfClosed(); if (connectionHttp.isStatelessMode()) { if (!connectionHttp.getAutoCommit()) { throw new IllegalStateException(Tag.PRODUCT + "execute can\'t be executed when auto commit is off."); } } debug("PreparedStatementHttp.execute : " + sql); lastExecuteIsRaw = true; // Check that all parameters values are set ParametersUtil.checkParameters(statementHolder); statementHolder.setPreparedStatement(true); statementHolder.setExecuteUpdate(false); statementHolder.setJoinResultSetMetaData(connectionHttp .isJoinResultSetMetaData()); statementHolder.setFetchSize(fetchSize); statementHolder.setMaxRows(maxRows); statementHolder.setQueryTimeout(queryTimeout); statementHolder.setEscapeProcessing(escapeProcessingInt); // Reset the fields values rsFromExecute = null; updateCount = -1; // Send order to Server to SQL Executor JdbcHttpExecuteRawTransfer jdbcHttpExecuteRawTransfer = new JdbcHttpExecuteRawTransfer( connectionHttp, connectionHttp.getAuthenticationToken()); receiveFileFromExecute = jdbcHttpExecuteRawTransfer .getFileFromExecuteRaw(statementHolder); localFilesExecuteResult.add(receiveFileFromExecute); debug("getFileFromexecuteOnServer() : " + receiveFileFromExecute); boolean fileResultSet = super.isFileResultSet(receiveFileFromExecute); try { if (DEBUG) { String fileContent = FileUtils .readFileToString(receiveFileFromExecute); System.out.println(fileContent); } } catch (IOException e2) { throw new SQLException(e2); } if (fileResultSet) { // Transform the Result Set in String back to an Result Set // (emulated) rsFromExecute = new ResultSetHttp(connectionHttp, statementHolder, this, receiveFileFromExecute); return true; } else { BufferedReader bufferedReader = null; String line1 = null; try { bufferedReader = new BufferedReader(new FileReader( receiveFileFromExecute)); line1 = bufferedReader.readLine(); } catch (IOException e1) { throw new SQLException(e1); } finally { IOUtils.closeQuietly(bufferedReader); } String updateCountStr = StringUtils.substringAfter(line1, "getUpdateCount="); try { updateCount = Integer.parseInt(updateCountStr); } catch (NumberFormatException e) { throw new SQLException(Tag.PRODUCT_PRODUCT_FAIL + e.getMessage(), new IOException(e.getMessage(), e)); } return false; } } /* * (non-Javadoc) * * @see org.kawanfw.sql.jdbc.StatementHttp#getUpdateCount() */ @Override public int getUpdateCount() throws SQLException { return updateCount; } /** * Moves to this Statement object's next result, returns * true if it is a ResultSet object, and * implicitly closes any current ResultSet object(s) obtained * with the method getResultSet. * *

* There are no more results when the following is true: * *

     *      (!getMoreResults() && (getUpdateCount() == -1)
     * 
* * @return true if the next result is a ResultSet * object; false if it is an update count or there are * no more results * @exception SQLException * if a database access error occurs * @see #execute */ public boolean getMoreResults() throws SQLException { // always return false for now: return false; } /** * Sets the designated parameter to SQL NULL. * *

* Note: You must specify the parameter's SQL type. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param sqlType * the SQL type code defined in java.sql.Types * @exception SQLException * if a database access error occurs */ public void setNull(int parameterIndex, int sqlType) throws SQLException { testIfClosed(); statementHolder.setNullParameter(parameterIndex, sqlType); } /** * Sets the designated parameter to the given Java boolean * value. The driver converts this to an SQL BIT value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setBoolean(int parameterIndex, boolean x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given Java short value. * The driver converts this to an SQL SMALLINT value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setShort(int parameterIndex, short x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given Java int value. * The driver converts this to an SQL INTEGER value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setInt(int parameterIndex, int x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given Java long value. * The driver converts this to an SQL BIGINT value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setLong(int parameterIndex, long x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given Java float value. * The driver converts this to an SQL FLOAT value when it sends * it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setFloat(int parameterIndex, float x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given Java double * value. The driver converts this to an SQL DOUBLE value when * it sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setDouble(int parameterIndex, double x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given * java.math.BigDecimal value. The driver converts this to an * SQL NUMERIC value when it sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement */ @Override public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given Java String * value. The driver converts this to an SQL VARCHAR or * LONGVARCHAR value (depending on the argument's size relative * to the driver's limits on VARCHAR values) when it sends it * to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setString(int parameterIndex, String x) throws SQLException { testIfClosed(); // x = TransportConverter.toTransportFormat(x); if (x != null && x.length() > connectionHttp.getMaxLengthForString()) { throw new SQLException("String is too big for upload: " + x.length() + " bytes. Maximum length authorized is: " + connectionHttp.getMaxLengthForString()); } statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given String object. * The driver converts this to a SQL NCHAR or * NVARCHAR or LONGNVARCHAR value (depending on * the argument's size relative to the driver's limits on * NVARCHAR values) when it sends it to the database. * * @param parameterIndex * of the first parameter is 1, the second is 2, ... * @param value * the parameter value * @throws SQLException * if parameterIndex does not correspond to a parameter marker * in the SQL statement; if the driver does not support national * character sets; if the driver can detect that a data * conversion error could occur; if a database access error * occurs; or this method is called on a closed * PreparedStatement * @throws SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.6 */ @Override public void setNString(int parameterIndex, String value) throws SQLException { testIfClosed(); // x = TransportConverter.toTransportFormat(x); if (value != null && value.length() > connectionHttp.getMaxLengthForString()) { throw new SQLException("String is too big for upload: " + value.length() + " bytes. Maximum length authorized is: " + connectionHttp.getMaxLengthForString()); } statementHolder.setParameter(parameterIndex, value, StatementHolder.SET_N_STRING); } /** * Sets the designated parameter to the given Java byte value. * The driver converts this to an SQL TINYINT value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setByte(int parameterIndex, byte x) throws SQLException { testIfClosed(); byte[] theByte = new byte[1]; theByte[0] = x; String encodedString = TransportConverter.toTransportFormat(theByte); // parameterValues.put(parameterIndex, hexString); statementHolder.setParameter(parameterIndex, encodedString); } /** * Sets the designated parameter to the given Java array of bytes. The * driver converts this to an SQL VARBINARY or * LONGVARBINARY (depending on the argument's size relative to * the driver's limits on VARBINARY values) when it sends it to * the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setBytes(int parameterIndex, byte[] x) throws SQLException { testIfClosed(); String encodedString = TransportConverter.toTransportFormat(x); // parameterValues.put(parameterIndex, hexString); statementHolder.setParameter(parameterIndex, encodedString); } /** * Sets the designated parameter to the given java.sql.Date * value. The driver converts this to an SQL DATE value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setDate(int parameterIndex, java.sql.Date x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given java.sql.Time * value. The driver converts this to an SQL TIME value when it * sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ public void setTime(int parameterIndex, java.sql.Time x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given * java.sql.Timestamp value. The driver converts this to an SQL * TIMESTAMP value when it sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @exception SQLException * if a database access error occurs */ @Override public void setTimestamp(int parameterIndex, java.sql.Timestamp x) throws SQLException { testIfClosed(); statementHolder.setParameter(parameterIndex, x); } /** *

* Sets the value of the designated parameter using the given object. The * second parameter must be of type Object; therefore, the * java.lang equivalent objects should be used for built-in * types. * *

* The JDBC specification specifies a standard mapping from Java * Object types to SQL types. The given argument will be * converted to the corresponding SQL type before being sent to the * database. * *

* Note that this method may be used to pass datatabase- specific abstract * data types, by using a driver-specific Java type. * * If the object is of a class implementing the interface * SQLData, the JDBC driver should call the method * SQLData.writeSQL to write it to the SQL data stream. If, on * the other hand, the object is of a class implementing Ref, * Blob, Clob, Struct, or * Array, the driver should pass it to the database as a value * of the corresponding SQL type. *

* This method throws an exception if there is an ambiguity, for example, if * the object is of a class implementing more than one of the interfaces * named above. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the object containing the input parameter value * @exception SQLException * if a database access error occurs or the type of the given * object is ambiguous */ @Override public void setObject(int parameterIndex, Object x) throws SQLException { testIfClosed(); if (x != null && x.toString().length() > connectionHttp .getMaxLengthForString()) { throw new SQLException("Object is too big for upload: " + x.toString().length() + " bytes. Maximum length authorized is: " + connectionHttp.getMaxLengthForString()); } statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given input stream. When a very * large binary value is input to a LONGVARBINARY parameter, it * may be more practical to send it via a java.io.InputStream * object. The data will be read from the stream as needed until end-of-file * is reached. * *

* Note: This stream object can either be a standard Java stream * object or your own subclass that implements the standard interface. *

* Note: Consult your JDBC driver documentation to determine if it * might be more efficient to use a version of setBinaryStream * which takes a length parameter. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the java input stream which contains the binary parameter * value * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @throws SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.6 */ @Override public void setBinaryStream(int parameterIndex, java.io.InputStream x) throws SQLException { testIfClosed(); this.setBinaryStream(parameterIndex, x, (long) -1); } /** * Add the files to the stack * * @param file * the local file, blob or clob * @param rawRemoteFileName * the remote filename */ protected void addFiles(File file, String rawRemoteFileName) { // HACK NDP if (!rawRemoteFileName.startsWith("/")) { rawRemoteFileName = "/" + rawRemoteFileName; } if (connectionHttp.isStatelessMode()) { connectionHttp.localFiles.add(file); connectionHttp.remoteFiles.add(rawRemoteFileName); } else { this.localFilesStatement.add(file); this.remoteFilesStatement.add(rawRemoteFileName); } } // /** // * Add InputStream to the stack // * @param in the input stream // * @param length the input stream length // * @param rawRemoteFileName the remote file naes // */ // protected void addInputStreams(InputStream in, long length, String // rawRemoteFileName) { // if (connectionHttp.isStatelessMode()) { // connectionHttp.localInputStreams.add(in); // connectionHttp.localInputStreamLengths.add(length); // connectionHttp.remoteFiles.add(rawRemoteFileName); // } else { // this.localInputStreams.add(in); // this.localInputStreamLengths.add(length); // this.remoteFilesStatement.add(rawRemoteFileName); // } // } /** * Sets the designated parameter to the given input stream, which will have * the specified number of bytes. When a very large binary value is input to * a LONGVARBINARY parameter, it may be more practical to send * it via a java.io.InputStream object. The data will be read * from the stream as needed until end-of-file is reached. * *

* Note: This stream object can either be a standard Java stream * object or your own subclass that implements the standard interface. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the java input stream which contains the binary parameter * value * @param length * the number of bytes in the stream * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement */ @Override public void setBinaryStream(int parameterIndex, java.io.InputStream x, int length) throws SQLException { testIfClosed(); this.setBinaryStream(parameterIndex, x, (long) length); } /** * Sets the designated parameter to the given input stream, which will have * the specified number of bytes. When a very large binary value is input to * a LONGVARBINARY parameter, it may be more practical to send * it via a java.io.InputStream object. The data will be read * from the stream as needed until end-of-file is reached. * *

* Note: This stream object can either be a standard Java stream * object or your own subclass that implements the standard interface. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the java input stream which contains the binary parameter * value * @param length * the number of bytes in the stream * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @since 1.6 */ @Override public void setBinaryStream(int parameterIndex, java.io.InputStream x, long length) throws SQLException { testIfClosed(); // Create the file from the input Stream, naming it on the table name FileNameFromBlobBuilder fileNameFromBlobBuilder = new FileNameFromBlobBuilder( sql, parameterIndex, false); String rawRemoteFileName = fileNameFromBlobBuilder.getFileName(); String dir = FrameworkFileUtil.getKawansoftTempDir(); File blobFile = new File(dir + File.separator + rawRemoteFileName); debug("rawRemoteFileName: " + rawRemoteFileName); debug("blobFile : " + blobFile); OutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(blobFile)); IOUtils.copy(x, out); } catch (IOException e) { throw new SQLException(e.getMessage()); } finally { IOUtils.closeQuietly(x); IOUtils.closeQuietly(out); } addFiles(blobFile, rawRemoteFileName); // Create the file from the input Stream, naming it on the table name // FileNameFromBlobBuilder fileNameFromBlobBuilder = new // FileNameFromBlobBuilder( // sql, parameterIndex, false); // String rawRemoteFileName = fileNameFromBlobBuilder.getFileName(); // // addInputStreams(x, length, rawRemoteFileName); // Ok. File is successfully uploaded! // Set the parameter using the file name InputStream inputStream = new TransportInputStream(rawRemoteFileName); // parameterValues.put(parameterIndex, inputStream); statementHolder.setParameter(parameterIndex, inputStream); } @Override public void setBlob(int parameterIndex, Blob x) throws SQLException { testIfClosed(); if (x instanceof BlobHttp) { BlobHttp blobHttp = (BlobHttp) x; // Close the underlying output stream, cleaner: blobHttp.close(); String rawRemoteFileName = blobHttp.getFile().getName(); debug("blobHttp.getFile(): " + blobHttp.getFile()); debug("rawRemoteFileName : " + rawRemoteFileName); addFiles(blobHttp.getFile(), rawRemoteFileName); // Ok. File is successfully uploaded! // Set the parameter using the file name InputStream inputStream = new TransportInputStream( rawRemoteFileName); // parameterValues.put(parameterIndex, inputStream); statementHolder.setParameter(parameterIndex, inputStream); } else { InputStream in = x.getBinaryStream(); setBinaryStream(parameterIndex, in, x.length()); } } @Override public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { testIfClosed(); setBinaryStream(parameterIndex, inputStream); } @Override public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { testIfClosed(); setBinaryStream(parameterIndex, inputStream, length); } @Override public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { setAsciiStream(parameterIndex, x); } @Override public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { setAsciiStream(parameterIndex, x); } @Override public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { testIfClosed(); // Create the file from the input Stream, naming it on the table name FileNameFromBlobBuilder fileNameFromBlobBuilder = new FileNameFromBlobBuilder( sql, parameterIndex, true); String rawRemoteFileName = fileNameFromBlobBuilder.getFileName(); String dir = FrameworkFileUtil.getKawansoftTempDir(); File clobFile = new File(dir + File.separator + rawRemoteFileName); debug("rawRemoteFileName: " + rawRemoteFileName); debug("blobFile : " + clobFile); Writer writer = null; try { BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(x)); writer = new BufferedWriter(new FileWriter(clobFile)); String line = null; while ((line = bufferedReader.readLine()) != null) { if (connectionHttp.isHtmlEncodingOn()) { line = HtmlConverter.toHtml(line); } writer.write(line + CR_LF); } } catch (IOException e) { throw new SQLException(e.getMessage()); } finally { IOUtils.closeQuietly(x); IOUtils.closeQuietly(writer); } addFiles(clobFile, rawRemoteFileName); // Ok. File is successfully uploaded! // Set the parameter using the file name TransportAsciiStream transportAsciiStream = new TransportAsciiStream( rawRemoteFileName); // parameterValues.put(parameterIndex, inputStream); statementHolder.setParameter(parameterIndex, transportAsciiStream); } /** * Sets the designated parameter to the given Reader object. * When a very large UNICODE value is input to a LONGVARCHAR * parameter, it may be more practical to send it via a * java.io.Reader object. The data will be read from the stream * as needed until end-of-file is reached. The JDBC driver will do any * necessary conversion from UNICODE to the database char format. * *

* Note: This stream object can either be a standard Java stream * object or your own subclass that implements the standard interface. *

* Note: Consult your JDBC driver documentation to determine if it * might be more efficient to use a version of * setCharacterStream which takes a length parameter. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param reader * the java.io.Reader object that contains the * Unicode data * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @throws SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.6 */ @Override public void setCharacterStream(int parameterIndex, java.io.Reader reader) throws SQLException { testIfClosed(); // Create the file from the input Stream, naming it on the table name FileNameFromBlobBuilder fileNameFromBlobBuilder = new FileNameFromBlobBuilder( sql, parameterIndex, true); String rawRemoteFileName = fileNameFromBlobBuilder.getFileName(); String dir = FrameworkFileUtil.getKawansoftTempDir(); File clobFile = new File(dir + File.separator + rawRemoteFileName); debug("rawFileName: " + rawRemoteFileName); debug("clobFile : " + clobFile); BufferedReader bufferedReader = null; Writer writer = null; try { bufferedReader = new BufferedReader(reader); writer = new BufferedWriter(new FileWriter(clobFile)); String line = null; while ((line = bufferedReader.readLine()) != null) { if (connectionHttp.isHtmlEncodingOn()) { line = HtmlConverter.toHtml(line); } writer.write(line + CR_LF); } } catch (IOException e) { throw new SQLException(e.getMessage()); } finally { IOUtils.closeQuietly(reader); IOUtils.closeQuietly(writer); } addFiles(clobFile, rawRemoteFileName); // Ok. File is successfully uploaded! // Set the parameter using the file name Reader transportReader = new TransportReader(rawRemoteFileName); statementHolder.setParameter(parameterIndex, transportReader); } /** * Sets the designated parameter to the given Reader object, * which is the given number of characters long. When a very large UNICODE * value is input to a LONGVARCHAR parameter, it may be more * practical to send it via a java.io.Reader object. The data * will be read from the stream as needed until end-of-file is reached. The * JDBC driver will do any necessary conversion from UNICODE to the database * char format. * *

* Note: This stream object can either be a standard Java stream * object or your own subclass that implements the standard interface. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param reader * the java.io.Reader object that contains the * Unicode data * @param length * the number of characters in the stream * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @since 1.2 */ @Override public void setCharacterStream(int parameterIndex, java.io.Reader reader, int length) throws SQLException { testIfClosed(); this.setCharacterStream(parameterIndex, reader); } /** * Sets the designated parameter to the given Reader object, * which is the given number of characters long. When a very large UNICODE * value is input to a LONGVARCHAR parameter, it may be more * practical to send it via a java.io.Reader object. The data * will be read from the stream as needed until end-of-file is reached. The * JDBC driver will do any necessary conversion from UNICODE to the database * char format. * *

* Note: This stream object can either be a standard Java stream * object or your own subclass that implements the standard interface. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param reader * the java.io.Reader object that contains the * Unicode data * @param length * the number of characters in the stream * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @since 1.6 */ @Override public void setCharacterStream(int parameterIndex, java.io.Reader reader, long length) throws SQLException { testIfClosed(); this.setCharacterStream(parameterIndex, reader); } @Override public void setClob(int parameterIndex, Clob x) throws SQLException { testIfClosed(); // Clob creation is not optimized (other file creation) , because if // htmlEncoding is on we must rewrite the file Reader reader = x.getCharacterStream(); setCharacterStream(parameterIndex, reader); } @Override public void setClob(int parameterIndex, Reader reader, long length) throws SQLException { testIfClosed(); setCharacterStream(parameterIndex, reader, length); } @Override public void setClob(int parameterIndex, Reader reader) throws SQLException { testIfClosed(); setCharacterStream(parameterIndex, reader); } /** * Clears the current parameter values immediately. *

* In general, parameter values remain in force for repeated use of a * statement. Setting a parameter value automatically clears its previous * value. However, in some cases it is useful to immediately release the * resources used by the current parameter values; this can be done by * calling the method clearParameters. * * @exception SQLException * if a database access error occurs */ @Override public void clearParameters() throws SQLException { statementHolder.clearParameters(); } // --------------------------JDBC 2.0----------------------------- /** * Adds a set of parameters to this PreparedStatement object's * batch of commands. * * @exception SQLException * if a database access error occurs * @see Statement#addBatch * @since 1.2 */ @Override public void addBatch() throws SQLException { // Check that all parameters values are set ParametersUtil.checkParameters(statementHolder); // Create a StatementHolder that contains only the parameter // and add it to the batchHolderList field: StatementHolder batchHolder = new StatementHolder( statementHolder.getParameterTypes(), statementHolder.getParameterStringValues(), statementHolder.isHtmlEncodingOn()); batchHolder.setPreparedStatement(true); batchHolder.setExecuteUpdate(true); batchHolderFileList.add(batchHolder); debug("batchHolder: " + batchHolder); } /** * Submits a batch of commands to the database for execution and if all * commands execute successfully, returns an array of update counts. The * int elements of the array that is returned are ordered to * correspond to the commands in the batch, which are ordered according to * the order in which they were added to the batch. The elements in the * array returned by the method executeBatch may be one of the * following: *

    *
  1. A number greater than or equal to zero -- indicates that the command * was processed successfully and is an update count giving the number of * rows in the database that were affected by the command's execution *
  2. A value of SUCCESS_NO_INFO -- indicates that the command * was processed successfully but that the number of rows affected is * unknown *

    * If one of the commands in a batch update fails to execute properly, this * method throws a BatchUpdateException, and a JDBC driver may * or may not continue to process the remaining commands in the batch. * However, the driver's behavior must be consistent with a particular DBMS, * either always continuing to process commands or never continuing to * process commands. If the driver continues processing after a failure, the * array returned by the method * BatchUpdateException.getUpdateCounts will contain as many * elements as there are commands in the batch, and at least one of the * elements will be the following: *

    *

  3. A value of EXECUTE_FAILED -- indicates that the command * failed to execute successfully and occurs only if a driver continues to * process commands after a command fails *
*

* A driver is not required to implement this method. The possible * implementations and return values have been modified in the Java 2 SDK, * Standard Edition, version 1.3 to accommodate the option of continuing to * proccess commands in a batch update after a * BatchUpdateException obejct has been thrown. * * @return an array of update counts containing one element for each command * in the batch. The elements of the array are ordered according to * the order in which commands were added to the batch. * @exception SQLException * if a database access error occurs or the driver does not * support batch statements. Throws * {@link BatchUpdateException} (a subclass of * SQLException) if one of the commands sent to * the database fails to execute properly or attempts to * return a result set. * @since 1.3 */ @Override public int[] executeBatch() throws SQLException { int updateCounts[] = new int[batchHolderFileList.size()]; if (batchHolderFileList.size() == 0) { return updateCounts; } JdbcHttpBatchTransfer jdbcHttpBatchTransfer = new JdbcHttpBatchTransfer( connectionHttp, connectionHttp.getAuthenticationToken()); String updateCountsStr = jdbcHttpBatchTransfer .getStringFromExecutePrepStatementBatchOnServer( statementHolder, batchHolderFileList); updateCounts = IntArrayTransport.fromJson(updateCountsStr); clearBatch(); return updateCounts; } /** * Sets the designated parameter to the given java.net.URL * value. The driver converts this to an SQL DATALINK value * when it sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the java.net.URL object to be set * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @throws SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ @Override public void setURL(int parameterIndex, URL x) throws SQLException { if (x == null) { throw new IllegalArgumentException("URL can not be null!"); } statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given java.sql.Array * object. The driver converts this to an SQL ARRAY value when * it sends it to the database. * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * an Array object that maps an SQL * ARRAY value * @exception SQLException * if parameterIndex does not correspond to a parameter * marker in the SQL statement; if a database access error * occurs or this method is called on a closed * PreparedStatement * @throws SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.2 */ public void setArray(int parameterIndex, Array x) throws SQLException { if (connectionHttp.isStatelessMode()) { throw new SQLException( ConnectionHttp.FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } if (x == null) { throw new IllegalArgumentException("Array can not be null!"); } statementHolder.setParameter(parameterIndex, x); } /** * Sets the designated parameter to the given java.sql.RowId * object. The driver converts this to a SQL ROWID value when * it sends it to the database * * @param parameterIndex * the first parameter is 1, the second is 2, ... * @param x * the parameter value * @throws SQLException * if parameterIndex does not correspond to a parameter marker * in the SQL statement; if a database access error occurs or * this method is called on a closed * PreparedStatement * @throws SQLFeatureNotSupportedException * if the JDBC driver does not support this method * * @since 1.6 */ @Override public void setRowId(int parameterIndex, RowId x) throws SQLException { if (connectionHttp.isStatelessMode()) { throw new SQLException( ConnectionHttp.FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } if (x == null) { throw new IllegalArgumentException("RowId can not be null!"); } statementHolder.setParameter(parameterIndex, x); } // // Not (yet) implemented methods // @Override public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setRef(int parameterIndex, Ref x) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public ResultSetMetaData getMetaData() throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public ParameterMetaData getParameterMetaData() throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setNClob(int parameterIndex, NClob value) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } @Override public void setNClob(int parameterIndex, Reader reader) throws SQLException { throw new SQLFeatureNotSupportedException( ConnectionHttp.KAWANFW_NOT_SUPPORTED_METHOD); } private static void debug(String s) { if (DEBUG) ClientLogger.getLogger().log(Level.WARNING, s); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy