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

src-main.org.awakefw.sql.jdbc.ConnectionHttp Maven / Gradle / Ivy

Go to download

Awake SQL is an open source framework that allows remote and secure JDBC access through HTTP.

The newest version!
/*
 * This file is part of Awake SQL. 
 * Awake SQL: Remote JDBC access over HTTP.                                    
 * Copyright (C) 2013,  KawanSoft SAS
 * (http://www.kawansoft.com). All rights reserved.                    
 *                                                                         
 * Awake SQL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.         
 *              
 * Awake SQL 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 General Public License
 * along with this program; if not, see .
 *
 * If you develop commercial activities using Awake SQL, you must: 
 * a) disclose and distribute all source code of your own product,
 * b) license your own product under the GNU General Public License.
 * 
 * You can be released from the requirements of the license by
 * purchasing a commercial license. Buying such a license will allow you 
 * to ship Awake SQL with your closed source products without disclosing 
 * the source code.
 *
 * For more information, please contact KawanSoft SAS at this
 * address: [email protected]
 * 
 * Any modifications to this file must keep this entire header
 * intact.
 */
package org.awakefw.sql.jdbc;

import java.io.File;
import java.io.IOException;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.List;
import java.util.Properties;
import java.util.Vector;

import org.apache.commons.io.FileUtils;
import org.awakefw.commons.api.client.AwakeProgressManager;
import org.awakefw.commons.api.client.HttpProtocolParameters;
import org.awakefw.commons.api.client.HttpProxy;
import org.awakefw.commons.jdbc.abstracts.AbstractConnection;
import org.awakefw.file.api.client.AwakeFileSession;
import org.awakefw.file.api.util.AwakeDebug;
import org.awakefw.file.api.util.DefaultParms;
import org.awakefw.file.api.util.HtmlConverter;
import org.awakefw.file.util.AwakeClientLogger;
import org.awakefw.file.util.KeepTempFilePolicyParms;
import org.awakefw.file.util.Tag;
import org.awakefw.sql.jdbc.http.JdbcHttpConnectionInfoTransfer;
import org.awakefw.sql.jdbc.http.JdbcHttpMetaDataTransfer;
import org.awakefw.sql.jdbc.http.JdbcHttpSavepointTransfer;
import org.awakefw.sql.jdbc.http.JdbcHttpStatementTransfer;
import org.awakefw.sql.jdbc.http.JdbcHttpTransactionTransfer;
import org.awakefw.sql.jdbc.http.JdbcHttpTransferUtil;
import org.awakefw.sql.jdbc.util.JdbcUtil;
import org.awakefw.sql.jdbc.util.StatementHolderFileList;
import org.awakefw.sql.json.StatementHolder;
import org.awakefw.sql.json.no_obfuscation.DatabaseMetaDataHolder;
import org.awakefw.sql.json.no_obfuscation.DatabaseMetaDataHolderTransport;
import org.awakefw.sql.version.Version;

/**
 * Creates and handle a HTTP Connection to SQLExecutor on Http Server.
 */

public class ConnectionHttp extends AbstractConnection implements Connection,
	Cloneable {

    public static final String FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE = Tag.AWAKE
	    + "This feature is not supported in stateless mode";

    public static final String AWAKE_NOT_SUPPORTED_METHOD = Tag.AWAKE
	    + "Method is not yet implemented in Awake SQL";

    /** Set to true to display/log debug info */
    private static boolean DEBUG = AwakeDebug.isSet(ConnectionHttp.class);

    /** The default maximum number of statement for transport in memory */
    private static int DEFAULT_MAX_STATEMENTS_FOR_MEMORY_TRANSPORT = 100;

    /** The username */
    private String username = null;

    /** The Authentication Token */
    private String authenticationToken = null;

    /**
     * The ServerCallerNew instance. May be reused for file transfers, per
     * example
     */
    private AwakeFileSession awakeFileSession = null;

    /** The host to use */
    private String url = null;

    /** The Http Proxy instance */
    private HttpProxy httpProxy = null;

    /** The Http Parameters instance */
    private HttpProtocolParameters httpProtocolParameters = null;

    /**
     * The calling/owner thread - if any - for the progress indicator management
     */
    private AwakeProgressManager awakeProgressManager = null;

    /**
     * Set to true if the user has closed the connection by a explicit call to
     * close()
     */
    private boolean isClosed = false;

    /**
     * The supported holdability is only CLOSE_CURSORS_AT_COMMIT in
     * statelessMode
     */
    private int holdability = ResultSet.CLOSE_CURSORS_AT_COMMIT;

    /** Autocommit local state */
    private boolean autoCommit = true;

    /** The holdability, false if user does not change it */
    private boolean readOnly = false;

    /** The transaction isolation level, -1 if user does not change it */
    private int transactionIsolation = -1;

    /** The list of statement holder are stored on a file */
    private StatementHolderFileList statementHolderFileList = null;

    /** The maximum number of statement for transport in memory */
    private int maxStatementsForMemoryTransport = DEFAULT_MAX_STATEMENTS_FOR_MEMORY_TRANSPORT;

    /**
     * if true, the Statement Parameters will be encrypted if the
     * HttpProtocolParameter is set
     */
    private boolean encryptStatementParameters = false;

    /**
     * The list of local files to uplaod and delete (in fire and forget mode) at
     * end of prepared statement
     */
    List localFiles = new Vector();

    /**
     * The list of remote uploaded files delete (in fire and forget mode) at end
     * of prepared statement
     */
    List remoteFiles = new Vector();

    /**
     * The result of the transfered ExecuteUpdate (last result if aucoCommit is
     * off)
     */
    String receiveFromExecuteUpdate = null;

    //
    // New fields for server stateless or connected mode
    //

    /** Says if we gare in stateless mode */
    private boolean statelessMode = false;

    /** The incremented number of Connections */
    private static int MAX_CONNECTION_NUMBER = 0;

    /** The connectionId Id to use */
    private String connectionId = null;

    /**
     * Public constructor for clone() - Must be public because AwakeConnection
     * uses now composition)
     * 
     * @param url
     *            the URL of the path to the AwakeSqlManager Servlet
     * @param username
     *            the user username
     * @param httpProxy
     *            the proxy parameters (maybe null if none)
     * @param httpProtocolParameters
     *            the http protocol parameters to set (maybe null if none)
     * @param awakeFileSession
     *            the actual Awake File Session
     * @param statelessMode
     *            says if server is stateless for client side
     */

    public ConnectionHttp(String url, String username, HttpProxy httpProxy,
	    HttpProtocolParameters httpProtocolParameters,
	    AwakeFileSession awakeFileSession, boolean statelessMode) {

	this.url = url;
	this.username = username;
	this.httpProxy = httpProxy;
	this.httpProtocolParameters = httpProtocolParameters;

	this.awakeFileSession = awakeFileSession.clone();
	this.authenticationToken = this.awakeFileSession
		.getAuthenticationToken();

	// The file that will contain the statements, one per line added
	this.statementHolderFileList = new StatementHolderFileList(this);

	// Build the transaction Id
	this.statelessMode = statelessMode;

	if (statelessMode) {
	    this.connectionId = "0"; // Important , will be transmitted to
	    // server
	} else {
	    this.connectionId = buildConnectionId();
	    JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer(
		    this, authenticationToken);

	    try {
		jdbcHttpTransactionTransfer.initRemoteConnection();
	    } catch (SQLException e) {
		throw new IllegalStateException(e);
	    }
	}

    }

    /**
     * Constructor Build the SQL/JDBC http connection with a proxy and http
     * protocol parameters, if necessary.
     * 
     * @param url
     *            the URL of the path to the AwakeSqlManager Servlet
     * @param username
     *            the user username
     * @param password
     *            the authentication password for username
     * @param httpProxy
     *            the proxy parameters (maybe null if none)
     * @param httpProtocolParameters
     *            the http protocol parameters to set (maybe null if none)
     * @param statelessMode
     *            if true, we are in stateless mode on the server
     * 
     * @throws IllegalArgumentException
     *             if url, username, password is null
     * @throws SQLException
     *             if any Exception occurs. The
     *             SQLException wraps the original
     *             Exception that may be accessed using
     *             {@link SQLException#getCause()}.
     * 
     */
    public ConnectionHttp(String url, String username, char[] password,
	    HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters,
	    boolean statelessMode) throws SQLException {
	// Try to username with ServerCallerNew or throw an SQLException

	if (username == null) {
	    throw new IllegalArgumentException("username can not be null!");
	}

	if (password == null) {
	    throw new IllegalArgumentException("password can not be null!");
	}

	if (url == null) {
	    throw new IllegalArgumentException("url can not be null!");
	}

	try {
	    this.url = url;
	    this.httpProxy = httpProxy;
	    this.httpProtocolParameters = httpProtocolParameters;
	    this.username = username;

	    // The file that will contain the statements, one per line added
	    this.statementHolderFileList = new StatementHolderFileList(this);

	    // Do the current username on the SQl Servlet
	    awakeFileSession = new AwakeFileSession(url, username, password,
		    httpProxy, httpProtocolParameters);

	    // Because awakeFileSession.url may have been updated from http://
	    // to https://, update this.url:
	    this.url = awakeFileSession.getUrl();

	    this.authenticationToken = awakeFileSession
		    .getAuthenticationToken();

	    // Build the connection Id
	    this.statelessMode = statelessMode;

	    if (statelessMode) {
		this.connectionId = "0"; // Important , will be transmitted to
		// server
	    } else {
		this.connectionId = buildConnectionId();
		JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer(
			this, authenticationToken);

		try {
		    jdbcHttpTransactionTransfer.initRemoteConnection();
		} catch (SQLException e) {
		    throw new IllegalStateException(e);
		}
	    }

	} catch (Exception e) {
	    JdbcHttpTransferUtil.wrapExceptionAsSQLException(e);
	}

    }

    /**
     * Constructor Build the SQL/JDBC http connection with a proxy and http
     * protocol parameters, if necessary.
     * 
     * @param url
     *            the URL of the path to the AwakeSqlManager Servlet
     * @param username
     *            the user username
     * @param password
     *            the authentication password for username
     * @param httpProxy
     *            the proxy parameters (maybe null if none)
     * @param httpProtocolParameters
     *            the http protocol parameters to set (maybe null if none)
     * 
     * @throws IllegalArgumentException
     *             if url, username, password is null
     * @throws SQLException
     *             if any Exception occurs. The
     *             SQLException wraps the original
     *             Exception that may be accessed using
     *             {@link SQLException#getCause()}.
     * 
     */
    public ConnectionHttp(String url, String username, char[] password,
	    HttpProxy httpProxy, HttpProtocolParameters httpProtocolParameters)
	    throws SQLException {
	this(url, username, password, httpProxy, httpProtocolParameters, false);
    }

    /**
     * Constructor Build the SQL/JDBC http connection with a proxy if necessary.
     * 
     * @param url
     *            the URL of the path to the AwakeSqlManager Servlet
     * @param username
     *            the user username
     * @param password
     *            the authentication password
     * @param httpProxy
     *            the proxy parameters (maybe null if none)
     * @throws SQLException
     *             The wrapped Sql Exception
     * @throws IllegalArgumentException
     *             if url, username, password is null
     * @throws SQLException
     *             if any Exception occurs. The
     *             SQLException wraps the original
     *             Exception that may be accessed using
     *             {@link SQLException#getCause()}.
     */
    public ConnectionHttp(String url, String username, char[] password,
	    HttpProxy httpProxy) throws SQLException {
	this(url, username, password, httpProxy, null);
    }

    /**
     * Constructor Build the SQL/JDBC Http connection.
     * 
     * @param url
     *            the URL of the path to the AwakeSqlManager Servlet
     * @param username
     *            the user username
     * @param password
     *            the authentication password
     * 
     * @throws IllegalArgumentException
     *             if url, username, password is null
     * @throws SQLException
     *             if any Exception occurs. The
     *             SQLException wraps the original
     *             Exception that may be accessed using
     *             {@link SQLException#getCause()}.
     */
    public ConnectionHttp(String url, String username, char[] password)
	    throws SQLException {
	this(url, username, password, null, null);
    }

    /**
     * Generate a new incremented Transaction Id
     * 
     * @return the new incremented Transaction Id
     */
    private static synchronized int getNextConnectionNumber() {
	MAX_CONNECTION_NUMBER++;
	return MAX_CONNECTION_NUMBER;
    }

    /**
     * Build a unique transaction Id for this username
     * 
     * @return the built transaction Id
     */
    private String buildConnectionId() {
	String connectionId = getNextConnectionNumber() + "_"
		+ JdbcUtil.getMacAddress();
	return connectionId;
    }

    /**
     * Says if Html Encoding is on for Clobs uploads/downloads
     * 
     * @return true if Html Encoding is on
     */
    boolean isHtmlEncodingOn() {
	boolean htmlEncoding = DefaultParms.DEFAULT_HTML_ENCODING_ON;
	if (httpProtocolParameters != null) {
	    htmlEncoding = httpProtocolParameters.isHtmlEncodingOn();
	}
	return htmlEncoding;
    }

    /**
     * add a StatementHolder to the StatementHolder list to execute
     * 
     * @param statementHolder
     *            the StatementHolder to add to the StatementHolder list to
     *            execute
     */
    void addStatementHolder(StatementHolder statementHolder)
	    throws SQLException {
	testIfClosed();
	this.statementHolderFileList.add(statementHolder);
    }

    /**
     * Reset the statement holder list
     */
    void resetStatementHolderList() throws SQLException {
	testIfClosed();
	this.statementHolderFileList.delete(); // closes and delete the file
	this.statementHolderFileList = new StatementHolderFileList(this);

    }

    /**
     * Returns the maximum length authorized foe a string
     * 
     * @return
     */
    int getMaxLengthForString() {

	int maxLengthForString = DefaultParms.DEFAULT_MAX_LENGTH_FOR_STRING;
	if (httpProtocolParameters != null) {
	    maxLengthForString = httpProtocolParameters.getMaxLengthForString();
	}
	return maxLengthForString;
    }

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

	if (awakeProgressManager != null) {
	    awakeFileSession.setAwakeProgressManager(awakeProgressManager);

	    long length = getLocalFilesLength();
	    // addPercentToLong(length, 5);

	    awakeProgressManager.setLengthToTransfer(length);
	}
	try {

	    for (int i = 0; i < localFiles.size(); i++) {
		// Do the upload
		debug("uploading file: " + localFiles.get(i));
		awakeFileSession.upload(localFiles.get(i), remoteFiles.get(i));
	    }

	} catch (Exception e) {
	    JdbcHttpTransferUtil.wrapExceptionAsSQLException(e);
	} finally {
	    if (awakeProgressManager != null) {
		awakeProgressManager.setProgress(100);
	    }

	    if (!KeepTempFilePolicyParms.KEEP_TEMP_FILE && !DEBUG) {
		if (localFiles != null) {
		    for (File localFile : localFiles) {
			localFile.delete();
		    }
		}
	    }
	}

    }

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

    /**
     * Add a file to the local files
     * 
     * @param file
     */
    void addLocalFile(File file) {
	if (file == null) {
	    throw new IllegalArgumentException(Tag.AWAKE_PRODUCT_FAIL
		    + "file can not be null.");
	}
	this.localFiles.add(file);
    }

    void addRemoteFile(String file) {
	if (file == null) {
	    throw new IllegalArgumentException(Tag.AWAKE_PRODUCT_FAIL
		    + "file can not be null.");
	}
	this.remoteFiles.add(file);
    }

    /**
     * Execute a remote sql execute update statement and get the string
     * 
     * @param sql
     * @return the result of the execute update
     */
    String getStringFromExecuteUpdateListOnServer() throws SQLException {
	testIfClosed();

	try {
	    // Upload each blob/clob parameters
	    this.uploadBlobParameters();
	} finally {
	    this.localFiles = new Vector();
	    this.remoteFiles = new Vector();
	}

	JdbcHttpStatementTransfer jdbcHttpStatementTransfer = new JdbcHttpStatementTransfer(
		this, authenticationToken);
	String result = jdbcHttpStatementTransfer
		.getStringFromExecuteUpdateListOnServer(statementHolderFileList);
	return result;

    }

    /**
     * Creates a Statement object for sending SQL statements to the
     * database. SQL statements without parameters are normally executed using
     * Statement objects. If the same SQL statement is executed
     * many times, it may be more efficient to use a
     * PreparedStatement object.
     * 

* Result sets created using the returned Statement object will * by default be type TYPE_FORWARD_ONLY and have a concurrency * level of CONCUR_READ_ONLY. * * @return a new default Statement object * @exception SQLException * if a database access error occurs */ @Override public Statement createStatement() throws SQLException { testIfClosed(); return new StatementHttp(this, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); } /** * Creates a Statement object that will generate * ResultSet objects with the given type and concurrency. This * method is the same as the createStatement method above, but * it allows the default result set type and concurrency to be overridden. * The holdability of the created result sets can be determined by calling * {@link #getHoldability}. * * @param resultSetType * a result set type; one of * ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @param resultSetConcurrency * a concurrency type; one of * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @return a new Statement object that will generate * ResultSet objects with the given type and * concurrency * @exception SQLException * if a database access error occurs, this method is called * on a closed connection or the given parameters are not * ResultSet constants indicating type and * concurrency * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method or this * method is not supported for the specified result set type * and result set concurrency. * @since 1.2 */ @Override public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { testIfClosed(); // We support only ResultSet.CONCUR_READ_ONLY if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.CONCUR_UPDATABLE is not supported."); } return new StatementHttp(this, resultSetType, resultSetConcurrency, getHoldability()); } /** * Creates a Statement object that will generate * ResultSet objects with the given type, concurrency, and * holdability. This method is the same as the createStatement * method above, but it allows the default result set type, concurrency, and * holdability to be overridden. * * @param resultSetType * one of the following ResultSet constants: * ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @param resultSetConcurrency * one of the following ResultSet constants: * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @param resultSetHoldability * one of the following ResultSet constants: * ResultSet.HOLD_CURSORS_OVER_COMMIT or * ResultSet.CLOSE_CURSORS_AT_COMMIT * @return a new Statement object that will generate * ResultSet objects with the given type, concurrency, * and holdability * @exception SQLException * if a database access error occurs, this method is called * on a closed connection or the given parameters are not * ResultSet constants indicating type, * concurrency, and holdability * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method or this * method is not supported for the specified result set type, * result set holdability and result set concurrency. * @see ResultSet * @since 1.4 */ @Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { testIfClosed(); // We support only ResultSet.CONCUR_READ_ONLY if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.CONCUR_UPDATABLE is not supported."); } // We support only ResultSet.CLOSE_CURSORS_AT_COMMIT if (resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.HOLD_CURSORS_OVER_COMMIT is not supported."); } return new StatementHttp(this, resultSetType, resultSetConcurrency, resultSetHoldability); } /** * Creates a CallableStatement object for calling database * stored procedures. The CallableStatement object provides * methods for setting up its IN and OUT parameters, and methods for * executing the call to a stored procedure. * *

* Note: This method is optimized for handling stored procedure call * statements. Some drivers may send the call statement to the database when * the method prepareCall is done; others may wait until the * CallableStatement object is executed. This has no direct * effect on users; however, it does affect which method throws certain * SQLExceptions. *

* Result sets created using the returned CallableStatement * object will by default be type TYPE_FORWARD_ONLY and have a * concurrency level of CONCUR_READ_ONLY. * * @param sql * an SQL statement that may contain one or more '?' parameter * placeholders. Typically this statement is a JDBC function call * escape string. * @return a new default CallableStatement object containing * the pre-compiled SQL statement * @exception SQLException * if a database access error occurs */ @Override public CallableStatement prepareCall(String sql) throws SQLException { testIfClosed(); return new CallableStatementHttp(this, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); } /** * Creates a CallableStatement object that will generate * ResultSet objects with the given type and concurrency. This * method is the same as the prepareCall method above, but it * allows the default result set type and concurrency to be overridden. * * @param sql * a String object that is the SQL statement to be * sent to the database; may contain on or more ? parameters * @param resultSetType * a result set type; one of * ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @param resultSetConcurrency * a concurrency type; one of * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @return a new CallableStatement object containing the * pre-compiled SQL statement that will produce * ResultSet objects with the given type and * concurrency * @exception SQLException * if a database access error occurs or the given parameters * are not ResultSet constants indicating type * and concurrency * @since 1.2 */ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { testIfClosed(); // We support only ResultSet.CONCUR_READ_ONLY if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.CONCUR_UPDATABLE is not supported."); } return new CallableStatementHttp(this, sql, resultSetType, resultSetConcurrency, getHoldability()); } /** * Creates a CallableStatement object that will generate * ResultSet objects with the given type and concurrency. This * method is the same as the prepareCall method above, but it * allows the default result set type, result set concurrency type and * holdability to be overridden. * * @param sql * a String object that is the SQL statement to be * sent to the database; may contain on or more ? parameters * @param resultSetType * one of the following ResultSet constants: * ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @param resultSetConcurrency * one of the following ResultSet constants: * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @param resultSetHoldability * one of the following ResultSet constants: * ResultSet.HOLD_CURSORS_OVER_COMMIT or * ResultSet.CLOSE_CURSORS_AT_COMMIT * @return a new CallableStatement object, containing the * pre-compiled SQL statement, that will generate * ResultSet objects with the given type, concurrency, * and holdability * @exception SQLException * if a database access error occurs or the given parameters * are not ResultSet constants indicating type, * concurrency, and holdability * @see ResultSet * @since 1.4 */ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { testIfClosed(); // We support only ResultSet.CONCUR_READ_ONLY if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.CONCUR_UPDATABLE is not supported."); } // We support only ResultSet.CLOSE_CURSORS_AT_COMMIT if (resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.HOLD_CURSORS_OVER_COMMIT is not supported."); } return new CallableStatementHttp(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability); } /** * Creates a PreparedStatement object for sending parameterized * SQL statements to the database. *

* A SQL statement with or without IN parameters can be pre-compiled and * stored in a PreparedStatement object. This object can then * be used to efficiently execute this statement multiple times. * *

* Note: This method is optimized for handling parametric SQL * statements that benefit from precompilation. If the driver supports * precompilation, the method prepareStatement will send the * statement to the database for precompilation. Some drivers may not * support precompilation. In this case, the statement may not be sent to * the database until the PreparedStatement object is executed. * This has no direct effect on users; however, it does affect which methods * throw certain SQLException objects. *

* Result sets created using the returned PreparedStatement * object will by default be type TYPE_FORWARD_ONLY and have a * concurrency level of CONCUR_READ_ONLY. * * @param sql * an SQL statement that may contain one or more '?' IN parameter * placeholders * @return a new default PreparedStatement object containing * the pre-compiled SQL statement * @exception SQLException * if a database access error occurs */ @Override public PreparedStatement prepareStatement(String sql) throws SQLException { testIfClosed(); return new PreparedStatementHttp(this, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.CLOSE_CURSORS_AT_COMMIT); } /** * * Creates a PreparedStatement object that will generate * ResultSet objects with the given type and concurrency. This * method is the same as the prepareStatement method above, but * it allows the default result set type and concurrency to be overridden. * The holdability of the created result sets can be determined by calling * {@link #getHoldability}. * * @param sql * a String object that is the SQL statement to be * sent to the database; may contain one or more '?' IN * parameters * @param resultSetType * a result set type; one of * ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @param resultSetConcurrency * a concurrency type; one of * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @return a new PreparedStatement object containing the pre-compiled SQL * statement that will produce ResultSet objects with * the given type and concurrency * @exception SQLException * if a database access error occurs, this method is called * on a closed connection or the given parameters are not * ResultSet constants indicating type and * concurrency * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method or this * method is not supported for the specified result set type * and result set concurrency. * @since 1.2 */ @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { testIfClosed(); // We support only ResultSet.CONCUR_READ_ONLY if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.CONCUR_UPDATABLE is not supported."); } return new PreparedStatementHttp(this, sql, resultSetType, resultSetConcurrency, getHoldability()); } /** * Creates a PreparedStatement object that will generate * ResultSet objects with the given type, concurrency, and * holdability. *

* This method is the same as the prepareStatement method * above, but it allows the default result set type, concurrency, and * holdability to be overridden. * * @param sql * a String object that is the SQL statement to be * sent to the database; may contain one or more '?' IN * parameters * @param resultSetType * one of the following ResultSet constants: * ResultSet.TYPE_FORWARD_ONLY, * ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @param resultSetConcurrency * one of the following ResultSet constants: * ResultSet.CONCUR_READ_ONLY or * ResultSet.CONCUR_UPDATABLE * @param resultSetHoldability * one of the following ResultSet constants: * ResultSet.HOLD_CURSORS_OVER_COMMIT or * ResultSet.CLOSE_CURSORS_AT_COMMIT * @return a new PreparedStatement object, containing the * pre-compiled SQL statement, that will generate * ResultSet objects with the given type, concurrency, * and holdability * @exception SQLException * if a database access error occurs, this method is called * on a closed connection or the given parameters are not * ResultSet constants indicating type, * concurrency, and holdability * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method or this * method is not supported for the specified result set type, * result set holdability and result set concurrency. * @see ResultSet * @since 1.4 */ @Override public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { testIfClosed(); // We support only ResultSet.CONCUR_READ_ONLY if (resultSetConcurrency == ResultSet.CONCUR_UPDATABLE) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.CONCUR_UPDATABLE is not supported."); } // We support only ResultSet.HOLD_CURSORS_OVER_COMMIT if (resultSetHoldability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw new SQLFeatureNotSupportedException( "Concurrency ResultSet.HOLD_CURSORS_OVER_COMMIT is not supported."); } return new PreparedStatementHttp(this, sql, resultSetType, resultSetConcurrency, resultSetHoldability); } /** * Creates a default PreparedStatement object that has the * capability to retrieve auto-generated keys. The given constant tells the * driver whether it should make auto-generated keys available for * retrieval. This parameter is ignored if the SQL statement is not an * INSERT statement, or an SQL statement able to return * auto-generated keys (the list of such statements is vendor-specific). *

* Note: This method is optimized for handling parametric SQL * statements that benefit from precompilation. If the driver supports * precompilation, the method prepareStatement will send the * statement to the database for precompilation. Some drivers may not * support precompilation. In this case, the statement may not be sent to * the database until the PreparedStatement object is executed. * This has no direct effect on users; however, it does affect which methods * throw certain SQLExceptions. *

* Result sets created using the returned PreparedStatement * object will by default be type TYPE_FORWARD_ONLY and have a * concurrency level of CONCUR_READ_ONLY. The holdability of * the created result sets can be determined by calling * {@link #getHoldability}. * * @param sql * an SQL statement that may contain one or more '?' IN parameter * placeholders * @param autoGeneratedKeys * a flag indicating whether auto-generated keys should be * returned; one of Statement.RETURN_GENERATED_KEYS * or Statement.NO_GENERATED_KEYS * @return a new PreparedStatement object, containing the * pre-compiled SQL statement, that will have the capability of * returning auto-generated keys * @exception SQLException * if a database access error occurs, this method is called * on a closed connection or the given parameter is not a * Statement constant indicating whether * auto-generated keys should be returned * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method with a * constant of Statement.RETURN_GENERATED_KEYS * @since 1.4 */ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { if (autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS && autoGeneratedKeys != Statement.NO_GENERATED_KEYS) { throw new SQLException( "Invalid parameter autoGeneratedKeys value. Must be 1 or 2. Valus is: " + autoGeneratedKeys); } return new PreparedStatementHttp(this, sql, autoGeneratedKeys); } /** * Creates a default PreparedStatement object capable of * returning the auto-generated keys designated by the given array. This * array contains the indexes of the columns in the target table that * contain the auto-generated keys that should be made available. The driver * will ignore the array if the SQL statement is not an INSERT * statement, or an SQL statement able to return auto-generated keys (the * list of such statements is vendor-specific). *

* An SQL statement with or without IN parameters can be pre-compiled and * stored in a PreparedStatement object. This object can then * be used to efficiently execute this statement multiple times. *

* Note: This method is optimized for handling parametric SQL * statements that benefit from precompilation. If the driver supports * precompilation, the method prepareStatement will send the * statement to the database for precompilation. Some drivers may not * support precompilation. In this case, the statement may not be sent to * the database until the PreparedStatement object is executed. * This has no direct effect on users; however, it does affect which methods * throw certain SQLExceptions. *

* Result sets created using the returned PreparedStatement * object will by default be type TYPE_FORWARD_ONLY and have a * concurrency level of CONCUR_READ_ONLY. The holdability of * the created result sets can be determined by calling * {@link #getHoldability}. * * @param sql * an SQL statement that may contain one or more '?' IN parameter * placeholders * @param columnIndexes * an array of column indexes indicating the columns that should * be returned from the inserted row or rows * @return a new PreparedStatement object, containing the * pre-compiled statement, that is capable of returning the * auto-generated keys designated by the given array of column * indexes * @exception SQLException * if a database access error occurs or this method is called * on a closed connection * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method * * @since 1.4 */ public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException { if (columnIndexes == null) { throw new SQLException("columnIndexes can not be null"); } return new PreparedStatementHttp(this, sql, columnIndexes); } /** * Creates a default PreparedStatement object capable of * returning the auto-generated keys designated by the given array. This * array contains the names of the columns in the target table that contain * the auto-generated keys that should be returned. The driver will ignore * the array if the SQL statement is not an INSERT statement, * or an SQL statement able to return auto-generated keys (the list of such * statements is vendor-specific). *

* An SQL statement with or without IN parameters can be pre-compiled and * stored in a PreparedStatement object. This object can then * be used to efficiently execute this statement multiple times. *

* Note: This method is optimized for handling parametric SQL * statements that benefit from precompilation. If the driver supports * precompilation, the method prepareStatement will send the * statement to the database for precompilation. Some drivers may not * support precompilation. In this case, the statement may not be sent to * the database until the PreparedStatement object is executed. * This has no direct effect on users; however, it does affect which methods * throw certain SQLExceptions. *

* Result sets created using the returned PreparedStatement * object will by default be type TYPE_FORWARD_ONLY and have a * concurrency level of CONCUR_READ_ONLY. The holdability of * the created result sets can be determined by calling * {@link #getHoldability}. * * @param sql * an SQL statement that may contain one or more '?' IN parameter * placeholders * @param columnNames * an array of column names indicating the columns that should be * returned from the inserted row or rows * @return a new PreparedStatement object, containing the * pre-compiled statement, that is capable of returning the * auto-generated keys designated by the given array of column names * @exception SQLException * if a database access error occurs or this method is called * on a closed connection * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method * * @since 1.4 */ public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException { if (columnNames == null) { throw new SQLException("columnNames can not be null"); } return new PreparedStatementHttp(this, sql, columnNames); } /** * Constructs an object that implements the Blob interface. The * object returned initially contains no data. The * setBinaryStream and setBytes methods of the * Blob interface may be used to add data to the * Blob. * * @return An object that implements the Blob interface * @throws SQLException * if an object that implements the Blob interface * can not be constructed, this method is called on a closed * connection or a database access error occurs. * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * * @since 1.6 */ @Override public Blob createBlob() throws SQLException { testIfClosed(); BlobHttp blob = new BlobHttp(); return blob; } /** * Constructs an object that implements the Clob interface. The * object returned initially contains no data. The * setAsciiStream, setCharacterStream and * setString methods of the Clob interface may be * used to add data to the Clob. * * @return An object that implements the Clob interface * @throws SQLException * if an object that implements the Clob interface * can not be constructed, this method is called on a closed * connection or a database access error occurs. * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * * @since 1.6 */ @Override public Clob createClob() throws SQLException { testIfClosed(); ClobHttp clob = new ClobHttp(); return clob; } /** * Retrieves the current auto-commit mode for this Connection * object. * * @return the current state of this Connection object's * auto-commit mode * @exception SQLException * if a database access error occurs * @see #setAutoCommit */ @Override public boolean getAutoCommit() throws SQLException { testIfClosed(); return this.autoCommit; } /** * Sets this connection's auto-commit mode to the given state. If a * connection is in auto-commit mode, then all its SQL statements will be * executed and committed as individual transactions. Otherwise, its SQL * statements are grouped into transactions that are terminated by a call to * either the method commit or the method rollback * . By default, new connections are in auto-commit mode. *

* The commit occurs when the statement completes or the next execute * occurs, whichever comes first. In the case of statements returning a * ResultSet object, the statement completes when the last row * of the ResultSet object has been retrieved or the * ResultSet object has been closed. In advanced cases, a * single statement may return multiple results as well as output parameter * values. In these cases, the commit occurs when all results and output * parameter values have been retrieved. *

* NOTE: If this method is called during a transaction, the * transaction is committed. * * @param autoCommit * true to enable auto-commit mode; * false to disable it * @exception SQLException * if a database access error occurs * @see #getAutoCommit */ @Override public void setAutoCommit(boolean autoCommit) throws SQLException { testIfClosed(); if (statelessMode) { if (autoCommit && !this.statementHolderFileList.isEmpty()) { try { // Execute all pending statements receiveFromExecuteUpdate = getStringFromExecuteUpdateListOnServer(); } finally { resetStatementHolderList(); // Safety reset of list } } } else { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); jdbcHttpTransactionTransfer.setAutoCommit(autoCommit); } this.autoCommit = autoCommit; } /** * Makes all changes made since the previous commit/rollback permanent and * releases any database locks currently held by this * Connection object. This method should be used only when * auto-commit mode has been disabled. * * @exception SQLException * if a database access error occurs or this * Connection object is in auto-commit mode * @see #setAutoCommit */ @Override public void commit() throws SQLException { testIfClosed(); if (statelessMode) { // Execute all pending statements if (!this.statementHolderFileList.isEmpty()) { try { receiveFromExecuteUpdate = getStringFromExecuteUpdateListOnServer(); } finally { resetStatementHolderList(); // Safety reset of list } } } else { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); jdbcHttpTransactionTransfer.commit(); } } /** * Undoes all changes made in the current transaction and releases any * database locks currently held by this Connection object. * This method should be used only when auto-commit mode has been disabled. * * @exception SQLException * if a database access error occurs or this * Connection object is in auto-commit mode * @see #setAutoCommit */ @Override public void rollback() throws SQLException { testIfClosed(); if (statelessMode) { resetStatementHolderList(); } else { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); jdbcHttpTransactionTransfer.rollback(); } } /** * Creates an unnamed savepoint in the current transaction and returns the * new Savepoint object that represents it. * * @return the new Savepoint object * @exception SQLException * if a database access error occurs or this * Connection object is currently in auto-commit * mode * @see Savepoint * @since 1.4 */ @Override public Savepoint setSavepoint() throws SQLException { if (statelessMode) { throw new SQLException(FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } else { JdbcHttpSavepointTransfer jdbcHttpSavepointTransfer = new JdbcHttpSavepointTransfer( this, authenticationToken); Savepoint savepoint = jdbcHttpSavepointTransfer.setSavepoint(); return savepoint; } } /** * Creates a savepoint with the given name in the current transaction and * returns the new Savepoint object that represents it. * * @param name * a String containing the name of the savepoint * @return the new Savepoint object * @exception SQLException * if a database access error occurs or this * Connection object is currently in auto-commit * mode * @see Savepoint * @since 1.4 */ @Override public Savepoint setSavepoint(String name) throws SQLException { if (statelessMode) { throw new SQLException(FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } else { JdbcHttpSavepointTransfer jdbcHttpSavepointTransfer = new JdbcHttpSavepointTransfer( this, authenticationToken); Savepoint savepoint = jdbcHttpSavepointTransfer.setSavepoint(name); return savepoint; } } /** * Undoes all changes made after the given Savepoint object was * set. *

* This method should be used only when auto-commit has been disabled. * * @param savepoint * the Savepoint object to roll back to * @exception SQLException * if a database access error occurs, the * Savepoint object is no longer valid, or this * Connection object is currently in auto-commit * mode * @see Savepoint * @see #rollback * @since 1.4 */ @Override public void rollback(Savepoint savepoint) throws SQLException { if (statelessMode) { throw new SQLException(FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } else { JdbcHttpSavepointTransfer jdbcHttpSavepointTransfer = new JdbcHttpSavepointTransfer( this, authenticationToken); jdbcHttpSavepointTransfer.rollback(savepoint); return; } } /** * Undoes all changes made after the given Savepoint object was * set. *

* This method should be used only when auto-commit has been disabled. * * @param savepoint * the Savepoint object to roll back to * @exception SQLException * if a database access error occurs, this method is called * while participating in a distributed transaction, this * method is called on a closed connection, the * Savepoint object is no longer valid, or this * Connection object is currently in auto-commit * mode * @exception SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see Savepoint * @see #rollback * @since 1.4 */ @Override public void releaseSavepoint(Savepoint savepoint) throws SQLException { if (statelessMode) { throw new SQLException(FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } else { JdbcHttpSavepointTransfer jdbcHttpSavepointTransfer = new JdbcHttpSavepointTransfer( this, authenticationToken); jdbcHttpSavepointTransfer.releaseSavepoint(savepoint); return; } } /** * Releases this Connection object's database and JDBC * resources immediately instead of waiting for them to be automatically * released. *

* Calling the method close on a Connection object * that is already closed is a no-op. *

* Note: A Connection object is automatically closed * when it is garbage collected. Certain fatal errors also close a * Connection object. * * @exception SQLException * if a database access error occurs */ @Override public void close() throws SQLException { if (this.isClosed) { return; } if (!statelessMode) { final ConnectionHttp theConnection = this; try { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( theConnection, authenticationToken); jdbcHttpTransactionTransfer.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.username = null; this.authenticationToken = null; this.httpProtocolParameters = null; this.authenticationToken = null; this.awakeFileSession = null; this.awakeProgressManager = null; this.statementHolderFileList = null; this.isClosed = true; } /** * Retrieves whether this Connection object has been closed. A * connection is closed if the method close has been called on * it or if certain fatal errors have occurred. This method is guaranteed to * return true only when it is called after the method * Connection.close has been called. *

* This method generally cannot be called to determine whether a connection * to a database is valid or invalid. A typical client can determine that a * connection is invalid by catching any exceptions that might be thrown * when an operation is attempted. * * @return true if this Connection object is * closed; false if it is still open * @exception SQLException * if a database access error occurs */ @Override public boolean isClosed() throws SQLException { return this.isClosed; } /** * Puts this connection in read-only mode as a hint to the driver to enable * database optimizations. * *

* Note: This method cannot be called during a transaction. * * @param readOnly * true enables read-only mode; false * disables it * @exception SQLException * if a database access error occurs or this method is called * during a transaction */ @Override public void setReadOnly(boolean readOnly) throws SQLException { testIfClosed(); if (!statelessMode) { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); jdbcHttpTransactionTransfer.setReadOnly(readOnly); } this.readOnly = readOnly; } /** * Retrieves whether this Connection object is in read-only * mode. * * @return true if this Connection object is * read-only; false otherwise * @exception SQLException * if a database access error occurs */ @Override public boolean isReadOnly() throws SQLException { testIfClosed(); if (!statelessMode) { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); this.readOnly = jdbcHttpTransactionTransfer.isReadOnly(); } return this.readOnly; } /** * Retrieves a DatabaseMetaData object that contains metadata * about the database to which this Connection object * represents a connection. The metadata includes information about the * database's tables, its supported SQL grammar, its stored procedures, the * capabilities of this connection, and so on. * * @return a DatabaseMetaData object for this * Connection object * @exception SQLException * if a database access error occurs */ @Override public DatabaseMetaData getMetaData() throws SQLException { testIfClosed(); // Retrieve the JSON formated DatabaseMetaDataHolder from host JdbcHttpMetaDataTransfer jdbcHttpMetaDataTransfer = new JdbcHttpMetaDataTransfer( this, this.getAuthenticationToken()); File file = jdbcHttpMetaDataTransfer .getFileFromCallMetaDataFunction("getMetaData"); String databaseMetaDataHolderString = null; try { databaseMetaDataHolderString = FileUtils.readFileToString(file); databaseMetaDataHolderString = HtmlConverter .fromHtml(databaseMetaDataHolderString); } catch (IOException e) { JdbcHttpTransferUtil.wrapExceptionAsSQLException(e); } if (!DEBUG && !KeepTempFilePolicyParms.KEEP_TEMP_FILE) { file.delete(); } // Format the DatabaseMetaDataHolder from JSON String DatabaseMetaDataHolder databaseMetaDataHolder = DatabaseMetaDataHolderTransport .fromJson(databaseMetaDataHolderString); // Build the final DatabaseMetaDataHttp instance DatabaseMetaDataHttp databaseMetaData = new DatabaseMetaDataHttp(this, databaseMetaDataHolder); return databaseMetaData; } /** * Sets the given catalog name in order to select a subspace of this * Connection object's database in which to work. *

* If the driver does not support catalogs, it will silently ignore this * request. * * @param catalog * the name of a catalog (subspace in this * Connection object's database) in which to work * @exception SQLException * if a database access error occurs * @see #getCatalog */ @Override public void setCatalog(String catalog) throws SQLException { // Do Nothing ==> Ignore silently } /** * Retrieves this Connection object's current catalog name. * * @return the current catalog name or null if there is none * @exception SQLException * if a database access error occurs * @see #setCatalog */ @Override public String getCatalog() throws SQLException { // Retrieve the JSON formated DatabaseMetaDataHolder from host JdbcHttpMetaDataTransfer jdbcHttpMetaDataTransfer = new JdbcHttpMetaDataTransfer( this, this.getAuthenticationToken()); File file = jdbcHttpMetaDataTransfer .getFileFromCallMetaDataFunction("getCatalog"); String catalog = null; try { catalog = FileUtils.readFileToString(file); if (catalog != null) { catalog = catalog.trim(); } catalog = HtmlConverter.fromHtml(catalog); } catch (IOException e) { JdbcHttpTransferUtil.wrapExceptionAsSQLException(e); } if (catalog.equals("null")) { catalog = null; } file.delete(); return catalog; } /** * Attempts to change the transaction isolation level for this * Connection object to the one given. The constants defined in * the interface Connection are the possible transaction * isolation levels. *

* Note: If this method is called during a transaction, the result is * implementation-defined. * * @param level * one of the following Connection constants: * Connection.TRANSACTION_READ_UNCOMMITTED, * Connection.TRANSACTION_READ_COMMITTED, * Connection.TRANSACTION_REPEATABLE_READ, or * Connection.TRANSACTION_SERIALIZABLE. (Note that * Connection.TRANSACTION_NONE cannot be used * because it specifies that transactions are not supported.) * @exception SQLException * if a database access error occurs, this method is called * on a closed connection or the given parameter is not one * of the Connection constants * @see DatabaseMetaData#supportsTransactionIsolationLevel * @see #getTransactionIsolation */ @Override public void setTransactionIsolation(int level) throws SQLException { testIfClosed(); if (level != Connection.TRANSACTION_READ_UNCOMMITTED && level != Connection.TRANSACTION_READ_COMMITTED && level != Connection.TRANSACTION_REPEATABLE_READ && level != Connection.TRANSACTION_SERIALIZABLE) { throw new SQLException("Illegal transaction isolation level: " + level); } if (!statelessMode) { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); jdbcHttpTransactionTransfer.setTransactionIsolation(level); } this.transactionIsolation = level; } /** * Retrieves the first warning reported by calls on this * Connection object. If there is more than one warning, * subsequent warnings will be chained to the first one and can be retrieved * by calling the method SQLWarning.getNextWarning on the * warning that was retrieved previously. *

* This method may not be called on a closed connection; doing so will cause * an SQLException to be thrown. * *

* Note: Subsequent warnings will be chained to this SQLWarning. * * @return the first SQLWarning object or null if * there are none * @exception SQLException * if a database access error occurs or this method is called * on a closed connection * @see SQLWarning */ @Override public SQLWarning getWarnings() throws SQLException { return null; } /** * Clears all warnings reported for this Connection object. * After a call to this method, the method getWarnings returns * null until a new warning is reported for this * Connection object. * * @exception SQLException * if a database access error occurs */ @Override public void clearWarnings() throws SQLException { // Does nothing } /** * Retrieves this Connection object's current transaction * isolation level. * * @return the current transaction isolation level, which will be one of the * following constants: * Connection.TRANSACTION_READ_UNCOMMITTED, * Connection.TRANSACTION_READ_COMMITTED, * Connection.TRANSACTION_REPEATABLE_READ, * Connection.TRANSACTION_SERIALIZABLE, or * Connection.TRANSACTION_NONE. * @exception SQLException * if a database access error occurs or this method is called * on a closed connection * @see #setTransactionIsolation */ @Override public int getTransactionIsolation() throws SQLException { testIfClosed(); // Ok, now get the default isolation level JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); this.transactionIsolation = jdbcHttpTransactionTransfer .getTransactionIsolation(); return this.transactionIsolation; } // --------------------------JDBC 3.0----------------------------- /** * Changes the default holdability of ResultSet objects created * using this Connection object to the given holdability. The * default holdability of ResultSet objects can be be * determined by invoking {@link DatabaseMetaData#getResultSetHoldability}. * * @param holdability * a ResultSet holdability constant; one of * ResultSet.HOLD_CURSORS_OVER_COMMIT or * ResultSet.CLOSE_CURSORS_AT_COMMIT * @throws SQLException * if a database access occurs, this method is called on a * closed connection, or the given parameter is not a * ResultSet constant indicating holdability * @exception SQLFeatureNotSupportedException * if the given holdability is not supported * @see #getHoldability * @see DatabaseMetaData#getResultSetHoldability * @see ResultSet * @since 1.4 */ @Override public void setHoldability(int holdability) throws SQLException { testIfClosed(); if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT && holdability != ResultSet.CLOSE_CURSORS_AT_COMMIT) { throw new SQLException("Illegal holdability: " + holdability); } if (!statelessMode) { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); jdbcHttpTransactionTransfer.setHoldability(holdability); } else { if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw new SQLFeatureNotSupportedException( "holdability ResultSet.HOLD_CURSORS_OVER_COMMIT is not supported"); } } this.holdability = holdability; } /** * Retrieves the current holdability of ResultSet objects * created using this Connection object. * * @return the holdability, one of * ResultSet.HOLD_CURSORS_OVER_COMMIT or * ResultSet.CLOSE_CURSORS_AT_COMMIT * @throws SQLException * if a database access error occurs or this method is called on * a closed connection * @see #setHoldability * @see DatabaseMetaData#getResultSetHoldability * @see ResultSet * @since 1.4 */ @Override public int getHoldability() throws SQLException { testIfClosed(); if (!statelessMode) { JdbcHttpTransactionTransfer jdbcHttpTransactionTransfer = new JdbcHttpTransactionTransfer( this, authenticationToken); this.holdability = jdbcHttpTransactionTransfer.getHoldability(); } return holdability; } /** * Returns true if the connection has not been closed and is still valid. * The driver shall submit a query on the connection or use some other * mechanism that positively verifies the connection is still valid when * this method is called. *

* The query submitted by the driver to validate the connection shall be * executed in the context of the current transaction. * * @param timeout * - The time in seconds to wait for the database operation used * to validate the connection to complete. If the timeout period * expires before the operation completes, this method returns * false. A value of 0 indicates a timeout is not applied to the * database operation. *

* @return true if the connection is valid, false otherwise * @exception SQLException * if the value supplied for timeout is less * then 0 * @since 1.6 *

* @see java.sql.DatabaseMetaData#getClientInfoProperties */ @Override public boolean isValid(int timeout) throws SQLException { if (statelessMode) { throw new SQLException(FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } else { JdbcHttpConnectionInfoTransfer jdbcHttpConnectionInfoTransfer = new JdbcHttpConnectionInfoTransfer( this, authenticationToken); boolean isValid = jdbcHttpConnectionInfoTransfer.isValid(timeout); return isValid; } } /** * Sets the value of the client info property specified by name to the value * specified by value. *

* Applications may use the * DatabaseMetaData.getClientInfoProperties method to determine * the client info properties supported by the driver and the maximum length * that may be specified for each property. *

* The driver stores the value specified in a suitable location in the * database. For example in a special register, session parameter, or system * table column. For efficiency the driver may defer setting the value in * the database until the next time a statement is executed or prepared. * Other than storing the client information in the appropriate place in the * database, these methods shall not alter the behavior of the connection in * anyway. The values supplied to these methods are used for accounting, * diagnostics and debugging purposes only. *

* The driver shall generate a warning if the client info name specified is * not recognized by the driver. *

* If the value specified to this method is greater than the maximum length * for the property the driver may either truncate the value and generate a * warning or generate a SQLClientInfoException. If the driver * generates a SQLClientInfoException, the value specified was * not set on the connection. *

* The following are standard client info properties. Drivers are not * required to support these properties however if the driver supports a * client info property that can be described by one of the standard * properties, the standard property name should be used. *

*

    *
  • ApplicationName - The name of the application currently utilizing the * connection
  • *
  • ClientUser - The name of the user that the application using the * connection is performing work for. This may not be the same as the user * name that was used in establishing the connection.
  • *
  • ClientHostname - The hostname of the computer the application using * the connection is running on.
  • *
*

* * @param name * The name of the client info property to set * @param value * The value to set the client info property to. If the value is * null, the current value of the specified property is cleared. *

* @throws SQLClientInfoException * if the database server returns an error while setting the * client info value on the database server or this method is * called on a closed connection *

* @since 1.6 */ @Override public void setClientInfo(String name, String value) throws SQLClientInfoException { JdbcHttpConnectionInfoTransfer jdbcHttpConnectionInfoTransfer = new JdbcHttpConnectionInfoTransfer( this, authenticationToken); jdbcHttpConnectionInfoTransfer.setClientInfo(name, value); } /** * Sets the value of the connection's client info properties. The * Properties object contains the names and values of the * client info properties to be set. The set of client info properties * contained in the properties list replaces the current set of client info * properties on the connection. If a property that is currently set on the * connection is not present in the properties list, that property is * cleared. Specifying an empty properties list will clear all of the * properties on the connection. See * setClientInfo (String, String) for more information. *

* If an error occurs in setting any of the client info properties, a * SQLClientInfoException is thrown. The * SQLClientInfoException contains information indicating which * client info properties were not set. The state of the client information * is unknown because some databases do not allow multiple client info * properties to be set atomically. For those databases, one or more * properties may have been set before the error occurred. *

* * @param properties * the list of client info properties to set *

* @see java.sql.Connection#setClientInfo(String, String) * setClientInfo(String, String) * @since 1.6 *

* @throws SQLClientInfoException * if the database server returns an error while setting the * clientInfo values on the database server or this method is * called on a closed connection *

*/ @Override public void setClientInfo(Properties properties) throws SQLClientInfoException { JdbcHttpConnectionInfoTransfer jdbcHttpConnectionInfoTransfer = new JdbcHttpConnectionInfoTransfer( this, authenticationToken); jdbcHttpConnectionInfoTransfer.setClientInfo(properties); } /** * Returns the value of the client info property specified by name. This * method may return null if the specified client info property has not been * set and does not have a default value. This method will also return null * if the specified client info property name is not supported by the * driver. *

* Applications may use the * DatabaseMetaData.getClientInfoProperties method to determine * the client info properties supported by the driver. *

* * @param name * The name of the client info property to retrieve *

* @return The value of the client info property specified *

* @throws SQLException * if the database server returns an error when fetching the * client info value from the database or this method is called * on a closed connection *

* @since 1.6 *

* @see java.sql.DatabaseMetaData#getClientInfoProperties */ @Override public String getClientInfo(String name) throws SQLException { JdbcHttpConnectionInfoTransfer jdbcHttpConnectionInfoTransfer = new JdbcHttpConnectionInfoTransfer( this, authenticationToken); String clientInfo = jdbcHttpConnectionInfoTransfer.getClientInfo(name); return clientInfo; } /** * Returns a list containing the name and current value of each client info * property supported by the driver. The value of a client info property may * be null if the property has not been set and does not have a default * value. *

* * @return A Properties object that contains the name and * current value of each of the client info properties supported by * the driver. *

* @throws SQLException * if the database server returns an error when fetching the * client info values from the database or this method is called * on a closed connection *

* @since 1.6 */ @Override public Properties getClientInfo() throws SQLException { JdbcHttpConnectionInfoTransfer jdbcHttpConnectionInfoTransfer = new JdbcHttpConnectionInfoTransfer( this, authenticationToken); Properties clientInfo = jdbcHttpConnectionInfoTransfer.getClientInfo(); return clientInfo; } @Override public Array createArrayOf(String typeName, Object[] elements) throws SQLException { if (statelessMode) { throw new SQLException(FEATURE_NOT_SUPPORTED_IN_STATELESS_MODE); } else { JdbcHttpConnectionInfoTransfer jdbcHttpConnectionInfoTransfer = new JdbcHttpConnectionInfoTransfer( this, authenticationToken); Array array = jdbcHttpConnectionInfoTransfer.createArrayOf( typeName, elements); return array; } } // // Utility dedicated methods for raw ConnectionHttp class that are not // Connection // /** * Returns the current Awake SQL Version. * * @return the Awake SQL Version */ public String getVersion() { return Version.getVersion(); } /** * Returns the URL of the path to the AwakeSqlManager Servlet. * * @return the URL of the path to the AwakeSqlManager Servlet */ public String getUrl() { return url; } /** * Returns the username in use. * * @return the username in use */ public String getUsername() { return this.username; } /** * Returns the Authentication Token * * @return the Authentication Token */ String getAuthenticationToken() { return authenticationToken; } /** * Returns the HttpProtocolParameters instance in use for the * Awake SQL session. * * @return the HttpProtocolParameters instance in use for the * Awake SQL session */ public HttpProtocolParameters getHttpProtocolParameters() { return this.httpProtocolParameters; } /** * Allows to specify an AwakeProgresManager to use. * * @param awakeProgressManager * the owner to set - that is the File Transfer Engine *

* @see org.awakefw.commons.api.client.AwakeProgressManager */ public void setAwakeProgressManager( AwakeProgressManager awakeProgressManager) { this.awakeProgressManager = awakeProgressManager; } /** * Returns the AwakeProgresManager in use. * * @return the AwakeProgresManager in use */ public AwakeProgressManager getAwakeProgressManager() { return awakeProgressManager; } /** * Returns the HttpProxy instance in use for this Awake session. * * @return the HttpProxy instance in use for this Awake session */ public HttpProxy getHttpProxy() { return this.httpProxy; } /** * Allows to get a copy of the current AwakeConnection: use it * to do some simultaneous operations in a different thread (in order to * avoid conflicts). */ @Override public Connection clone() { Connection connectionHttp = new ConnectionHttp(this.url, this.username, this.httpProxy, this.httpProtocolParameters, awakeFileSession, statelessMode); return connectionHttp; } /** * Returns the http status code of the last executed JDBC command that * called the remote Awake SQL Manager. * * @return the http status code of the last executed JDBC command that * called the remote Awake SQL Manager. 0 means the status could not * be returned. */ public int getHttpStatusCode() { if (awakeFileSession != null) { return awakeFileSession.getHttpStatusCode(); } else { return 0; } } /** * Gets the current AwakeFileSession instance (used for file * transfers of Clobs and Blobs). *

* * @return the awakeFileSession instance (to be used for file transfers, per * example) */ public AwakeFileSession getAwakeFileSession() { return awakeFileSession; } /** * Returns true if the statement are to be encrypted. * * @return true if the statement are to be encrypted. (Default to false). */ public boolean isEncryptStatementParameters() { return this.encryptStatementParameters; } /** * Set if the statement parameters are to be encrypted * * @param encryptStatementParameters * true if the statement parameters are to be encrypted, else * false */ public void setEncryptStatementParameters(boolean encryptStatementParameters) { this.encryptStatementParameters = encryptStatementParameters; } /** * Returns the maximum Number Of Statements that may be transported in * memory. If maximum is reached, transport is done using a file. * * @return the maximum Number Of Statements that may be transported in * memory. */ public int getMaxStatementsForMemoryTransport() { return this.maxStatementsForMemoryTransport; } /** * Sets the maximum Number Of Statements that may be transported in memory * from client to server. if maximum is reached, transport is done using a * file. * * @param maxStatementsForMemoryTransport * the maximum Number Of Statements that may be transported in * memory. * */ public void setMaxStatementsForMemoryTransport( int maxStatementsForMemoryTransport) { this.maxStatementsForMemoryTransport = maxStatementsForMemoryTransport; } /** * Test if a connection is still open * * @throws SQLException * it the Connection is closed */ private void testIfClosed() throws SQLException { if (isClosed()) { throw new SQLException("This AwakeConnection is closed!"); } } /** * Says if session is in stateless mode when connecting to the server. * * @return true if session is in stateless mode when connecting to the * server */ public boolean isStatelessMode() { return statelessMode; } /** * @return the connectionId */ public String getConnectionId() { return connectionId; } /** * Debug tool * * @param s */ private void debug(String s) { if (DEBUG) { AwakeClientLogger.log(s); } } } // En





© 2015 - 2025 Weber Informatics LLC | Privacy Policy