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

org.drizzle.jdbc.DrizzleConnection Maven / Gradle / Ivy

There is a newer version: 1.4
Show newest version
/*
 * Drizzle-JDBC
 *
 * Copyright (c) 2009-2011, Marcus Eriksson
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following
 * conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided with the distribution.
 *  Neither the name of the driver nor the names of its contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.drizzle.jdbc;

import org.drizzle.jdbc.internal.SQLExceptionMapper;
import org.drizzle.jdbc.internal.common.BinlogDumpException;
import org.drizzle.jdbc.internal.common.DefaultParameterizedBatchHandlerFactory;
import org.drizzle.jdbc.internal.common.ParameterizedBatchHandlerFactory;
import org.drizzle.jdbc.internal.common.Protocol;
import org.drizzle.jdbc.internal.common.QueryException;
import org.drizzle.jdbc.internal.common.Utils;
import org.drizzle.jdbc.internal.common.packet.RawPacket;
import org.drizzle.jdbc.internal.common.query.QueryFactory;

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.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * A JDBC Connection.
 * 

* User: marcuse Date: Jan 14, 2009 Time: 7:47:37 AM */ public final class DrizzleConnection implements Connection, ReplicationConnection { /** * the protocol to communicate with. */ private final Protocol protocol; /** * save point count - to generate good names for the savepoints. */ private int savepointCount = 0; /** * the properties for the client. */ private final Properties clientInfoProperties; /** * a query factory. */ private final QueryFactory queryFactory; private ParameterizedBatchHandlerFactory parameterizedBatchHandlerFactory; /** * Executor that keeps track of timeouts for statements * * Works having just one thread for this since it is not legal to have several executing queries on the same connection! */ private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor(); /** * Creates a new connection with a given protocol and query factory. * * @param protocol the protocol to use. * @param queryFactory the query factory to use. */ public DrizzleConnection(final Protocol protocol, final QueryFactory queryFactory) { this.protocol = protocol; clientInfoProperties = new Properties(); this.queryFactory = queryFactory; } /** * creates a new statement. * * @return a statement * @throws SQLException if we cannot create the statement. */ public Statement createStatement() throws SQLException { return new DrizzleStatement(protocol, this, queryFactory); } /** * creates a new prepared statement. Only client side prepared statement emulation right now. * * @param sql the query. * @return a prepared statement. * @throws SQLException if there is a problem preparing the statement. */ public PreparedStatement prepareStatement(final String sql) throws SQLException { if (parameterizedBatchHandlerFactory == null) { this.parameterizedBatchHandlerFactory = new DefaultParameterizedBatchHandlerFactory(); } final String strippedQuery = Utils.stripQuery(sql); return new DrizzlePreparedStatement(protocol, this, strippedQuery, queryFactory, parameterizedBatchHandlerFactory.get(strippedQuery, protocol)); } /** * not implemented. * * @param sql unused * @return nothing. * @throws SQLException always since this is not implemented. */ public CallableStatement prepareCall(final String sql) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Stored procedures not supported"); } /** * currently does nothing. //TODO: implement * * @param sql * @return * @throws SQLException */ public String nativeSQL(final String sql) throws SQLException { return sql; } /** * Sets whether this connection is auto commited. * * @param autoCommit if it should be auto commited. * @throws SQLException if something goes wrong talking to the server. */ public void setAutoCommit(final boolean autoCommit) throws SQLException { Statement stmt = createStatement(); String clause; if(autoCommit) { clause = "1"; } else { clause = "0"; } stmt.executeUpdate("set autocommit="+clause); } /** * returns true if statements on this connection are auto commited. * * @return true if auto commit is on. * @throws SQLException */ public boolean getAutoCommit() throws SQLException { Statement stmt = createStatement(); ResultSet rs = stmt.executeQuery("select @@autocommit"); rs.next(); boolean autocommit = rs.getBoolean(1); rs.close(); stmt.close(); return autocommit; } /** * sends commit to the server. * * @throws SQLException if there is an error commiting. */ public void commit() throws SQLException { try { protocol.commit(); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * rolls back a transaction. * * @throws SQLException if there is an error rolling back. */ public void rollback() throws SQLException { try { protocol.rollback(); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * close the connection. * * @throws SQLException if there is a problem talking to the server. */ public void close() throws SQLException { try { this.timeoutExecutor.shutdown(); protocol.close(); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * checks if the connection is closed. * * @return true if the connection is closed * @throws SQLException if the connection cannot be closed. */ public boolean isClosed() throws SQLException { return protocol.isClosed(); } /** * returns the meta data about the database. * * @return meta data about the db. * @throws SQLException if there is a problem creating the meta data. */ public DatabaseMetaData getMetaData() throws SQLException { return new CommonDatabaseMetaData.Builder(protocol.getDatabaseType(), this). url("jdbc:drizzle://" + protocol.getHost() + ":" + protocol.getPort() + "/" + protocol.getDatabase()). username(protocol.getUsername()). version(protocol.getServerVersion()). databaseProductName(protocol.getDatabaseType().getDatabaseName()). build(); } /** * Sets whether this connection is read only. * * @param readOnly true if it should be read only. * @throws SQLException if there is a problem */ public void setReadOnly(final boolean readOnly) throws SQLException { protocol.setReadonly(readOnly); } /** * Retrieves whether this Connection object is in read-only mode. * * @return true if this Connection object is read-only; false otherwise * @throws java.sql.SQLException SQLException if a database access error occurs or this method is called on a closed * connection */ public boolean isReadOnly() throws SQLException { return false; } /** * 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 * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @see #getCatalog */ public void setCatalog(final String catalog) throws SQLException { // silently ignored since drizzle does not support catalogs } /** * Retrieves this Connection object's current catalog name. *

* catalogs are not supported in drizzle *

* TODO: Explain the wrapper interface to be able to change database * * @return the current catalog name or null if there is none * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @see #setCatalog */ public String getCatalog() throws SQLException { return null; } /** * 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.) * @throws java.sql.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 java.sql.DatabaseMetaData#supportsTransactionIsolationLevel * @see #getTransactionIsolation */ public void setTransactionIsolation(final int level) throws SQLException { String query = "SET SESSION TRANSACTION ISOLATION LEVEL"; switch (level) { case Connection.TRANSACTION_READ_UNCOMMITTED: query += " READ UNCOMMITTED"; break; case Connection.TRANSACTION_READ_COMMITTED: query += " READ COMMITTED"; break; case Connection.TRANSACTION_REPEATABLE_READ: query += " REPEATABLE READ"; break; case Connection.TRANSACTION_SERIALIZABLE: query += " SERIALIZABLE"; break; default: throw SQLExceptionMapper.getSQLException("Unsupported transaction isolation level"); } try { protocol.executeQuery(queryFactory.createQuery(query)); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * 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. * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @see #setTransactionIsolation */ public int getTransactionIsolation() throws SQLException { final Statement stmt = createStatement(); try { final ResultSet rs = stmt.executeQuery("SELECT @@tx_isolation"); rs.next(); final String response = rs.getString(1); if (response.equals("REPEATABLE-READ")) { return Connection.TRANSACTION_REPEATABLE_READ; } if (response.equals("READ-UNCOMMITTED")) { return Connection.TRANSACTION_READ_UNCOMMITTED; } if (response.equals("READ-COMMITTED")) { return Connection.TRANSACTION_READ_COMMITTED; } if (response.equals("SERIALIZABLE")) { return Connection.TRANSACTION_SERIALIZABLE; } } finally { stmt.close(); } throw SQLExceptionMapper.getSQLException("Could not get transaction isolation level"); } /** * Not yet implemented: Protocol needs to store any warnings related to connections *

*

* 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 * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @see java.sql.SQLWarning */ 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. * * @throws java.sql.SQLException SQLException if a database access error occurs or this method is called on a closed * connection */ public void clearWarnings() throws SQLException { } /** * 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 * @throws java.sql.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 */ public Statement createStatement(final int resultSetType, final int resultSetConcurrency) throws SQLException { // for now resultSetType and resultSetConcurrency are ignored // TODO: fix return createStatement(); } /** * 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 * @throws java.sql.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 */ public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { // for now resultSetType and resultSetConcurrency are ignored // TODO: fix return prepareStatement(sql); } /** * 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. 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 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 * @throws java.sql.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 * @throws java.sql.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. */ public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Stored procedures not supported"); } /** * Retrieves the Map object associated with this Connection object. Unless the application * has added an entry, the type map returned will be empty. * * @return the java.util.Map object associated with this Connection object * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see #setTypeMap * @since 1.2 */ public Map> getTypeMap() throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not yet supported"); } /** * Installs the given TypeMap object as the type map for this Connection object. The type * map will be used for the custom mapping of SQL structured types and distinct types. * * @param map the java.util.Map object to install as the replacement for this Connection * object's default type map * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed connection or * the given parameter is not a java.util.Map object * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see #getTypeMap */ public void setTypeMap(final Map> map) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not yet supported"); } /** * 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 java.sql.DatabaseMetaData#getResultSetHoldability}. * * @param holdability a ResultSet holdability constant; one of ResultSet.HOLD_CURSORS_OVER_COMMIT * or ResultSet.CLOSE_CURSORS_AT_COMMIT * @throws java.sql.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 * @throws java.sql.SQLFeatureNotSupportedException * if the given holdability is not supported * @see #getHoldability * @see java.sql.DatabaseMetaData#getResultSetHoldability * @see java.sql.ResultSet * @since 1.4 */ public void setHoldability(final int holdability) throws SQLException { if (holdability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw SQLExceptionMapper.getFeatureNotSupportedException("Only holding cursors over commit is supported"); } } /** * 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 java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @see #setHoldability * @see java.sql.DatabaseMetaData#getResultSetHoldability * @see java.sql.ResultSet * @since 1.4 */ public int getHoldability() throws SQLException { return ResultSet.HOLD_CURSORS_OVER_COMMIT; } /** * Creates an unnamed savepoint in the current transaction and returns the new Savepoint object that * represents it. *

*

if setSavepoint is invoked outside of an active transaction, a transaction will be started at this newly * created savepoint. * * @return the new Savepoint object * @throws java.sql.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 or this * Connection object is currently in auto-commit mode * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see java.sql.Savepoint * @since 1.4 */ public Savepoint setSavepoint() throws SQLException { return setSavepoint("unnamed"); } /** * Creates a savepoint with the given name in the current transaction and returns the new Savepoint * object that represents it. *

*

if setSavepoint is invoked outside of an active transaction, a transaction will be started at this newly * created savepoint. * * @param name a String containing the name of the savepoint * @return the new Savepoint object * @throws java.sql.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 or this * Connection object is currently in auto-commit mode * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see java.sql.Savepoint * @since 1.4 */ public Savepoint setSavepoint(final String name) throws SQLException { final Savepoint drizzleSavepoint = new DrizzleSavepoint(name, savepointCount++); try { protocol.setSavepoint(drizzleSavepoint.toString()); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } return drizzleSavepoint; } /** * 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 * @throws java.sql.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 * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see java.sql.Savepoint * @see #rollback * @since 1.4 */ public void rollback(final Savepoint savepoint) throws SQLException { try { protocol.rollback(savepoint.toString()); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * Removes the specified Savepoint and subsequent Savepoint objects from the current * transaction. Any reference to the savepoint after it have been removed will cause an SQLException to * be thrown. * * @param savepoint the Savepoint object to be removed * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed connection or * the given Savepoint object is not a valid savepoint in the current * transaction * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ public void releaseSavepoint(final Savepoint savepoint) throws SQLException { try { protocol.releaseSavepoint(savepoint.toString()); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * 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 * @throws java.sql.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 * @throws java.sql.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 java.sql.ResultSet * @since 1.4 */ public Statement createStatement(final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) { throw SQLExceptionMapper.getFeatureNotSupportedException("Only read-only result sets allowed"); } if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw SQLExceptionMapper.getFeatureNotSupportedException( "Cursors are always kept when sending commit (they are only client-side)"); } return createStatement(); } /** * 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 * @throws java.sql.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 * @throws java.sql.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 java.sql.ResultSet * @since 1.4 */ public PreparedStatement prepareStatement(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { if (resultSetConcurrency != ResultSet.CONCUR_READ_ONLY) { throw SQLExceptionMapper.getFeatureNotSupportedException("Only read-only result sets allowed"); } if (resultSetHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) { throw SQLExceptionMapper.getFeatureNotSupportedException( "Cursors are always kept when sending commit (they are only client-side)"); } // resultSetType is ignored since we always are scroll insensitive return prepareStatement(sql); } /** * 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 * @throws java.sql.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 * @throws java.sql.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 java.sql.ResultSet * @since 1.4 */ public CallableStatement prepareCall(final String sql, final int resultSetType, final int resultSetConcurrency, final int resultSetHoldability) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Prepared statements are not supported"); } /** * 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 * @throws java.sql.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 * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method with a constant of * Statement.RETURN_GENERATED_KEYS * @since 1.4 */ public PreparedStatement prepareStatement(final String sql, final int autoGeneratedKeys) throws SQLException { // autoGeneratedKeys are ignored since we always receive them for free with drizzle return prepareStatement(sql); } /** * 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 * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ public PreparedStatement prepareStatement(final String sql, final int[] columnIndexes) throws SQLException { if (columnIndexes != null && columnIndexes.length == 1 && columnIndexes[0] == 1) { return prepareStatement(sql); } throw SQLExceptionMapper.getSQLException("Only one auto generated key is supported, and it is on position 1"); } /** * 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 * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed connection * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ public PreparedStatement prepareStatement(final String sql, final String[] columnNames) throws SQLException { if (columnNames != null && columnNames.length == 1 && columnNames[0].equals("insert_id")) { return prepareStatement(sql); } throw SQLExceptionMapper.getSQLException("Only one auto generated key is supported, and it is called insert_id"); } /** * 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 java.sql.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. * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * @since 1.6 */ public Clob createClob() throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not yet supported"); } /** * 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 java.sql.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. * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * @since 1.6 */ public Blob createBlob() throws SQLException { return new DrizzleBlob(); } /** * Constructs an object that implements the NClob interface. The object returned initially contains no * data. The setAsciiStream, setCharacterStream and setString methods of the * NClob interface may be used to add data to the NClob. * * @return An object that implements the NClob interface * @throws java.sql.SQLException if an object that implements the NClob interface can not be * constructed, this method is called on a closed connection or a database access * error occurs. * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * @since 1.6 */ public java.sql.NClob createNClob() throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("NClobs not supported"); } /** * Constructs an object that implements the SQLXML interface. The object returned initially contains no * data. The createXmlStreamWriter object and setString method of the SQLXML * interface may be used to add data to the SQLXML object. * * @return An object that implements the SQLXML interface * @throws java.sql.SQLException if an object that implements the SQLXML interface can not be * constructed, this method is called on a closed connection or a database access * error occurs. * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * @since 1.6 */ public java.sql.SQLXML createSQLXML() throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not supported"); } /** * 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 * @throws java.sql.SQLException if the value supplied for timeout is less then 0 * @see java.sql.DatabaseMetaData#getClientInfoProperties * @since 1.6 *

*/ public boolean isValid(final int timeout) throws SQLException { try { return protocol.ping(); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * 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 java.sql.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 */ public void setClientInfo(final String name, final String value) throws java.sql.SQLClientInfoException { this.clientInfoProperties.setProperty(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 *

* @throws java.sql.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 *

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

*/ public void setClientInfo(final Properties properties) throws java.sql.SQLClientInfoException { // TODO: actually use these! for (final String key : properties.stringPropertyNames()) { this.clientInfoProperties.setProperty(key, properties.getProperty(key)); } } /** * 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 java.sql.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 *

* @see java.sql.DatabaseMetaData#getClientInfoProperties * @since 1.6 *

*/ public String getClientInfo(final String name) throws SQLException { return clientInfoProperties.getProperty(name); } /** * 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 java.sql.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 */ public Properties getClientInfo() throws SQLException { return clientInfoProperties; } /** * Factory method for creating Array objects. *

* Note: When createArrayOf is used to create an array object that maps to a primitive data * type, then it is implementation-defined whether the Array object is an array of that primitive data * type or an array of Object. *

* Note: The JDBC driver is responsible for mapping the elements Object array to the default * JDBC SQL type defined in java.sql.Types for the given class of Object. The default mapping is * specified in Appendix B of the JDBC specification. If the resulting JDBC type is not the appropriate type for * the given typeName then it is implementation defined whether an SQLException is thrown or the driver * supports the resulting conversion. * * @param typeName the SQL name of the type the elements of the array map to. The typeName is a database-specific * name which may be the name of a built-in type, a user-defined type or a standard SQL type * supported by this database. This is the value returned by Array.getBaseTypeName * @param elements the elements that populate the returned object * @return an Array object whose elements map to the specified SQL type * @throws java.sql.SQLException if a database error occurs, the JDBC type is not appropriate for the typeName and * the conversion is not supported, the typeName is null or this method is called on a * closed connection * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * @since 1.6 */ public Array createArrayOf(final String typeName, final Object[] elements) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not yet supported"); } /** * Factory method for creating Struct objects. * * @param typeName the SQL type name of the SQL structured type that this Struct object maps to. The * typeName is the name of a user-defined type that has been defined for this database. It is the * value returned by Struct.getSQLTypeName. * @param attributes the attributes that populate the returned object * @return a Struct object that maps to the given SQL type and is populated with the given attributes * @throws java.sql.SQLException if a database error occurs, the typeName is null or this method is called on a * closed connection * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this data type * @since 1.6 */ public Struct createStruct(final String typeName, final Object[] attributes) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not yet supported"); } /** * Returns an object that implements the given interface to allow access to non-standard methods, or standard * methods not exposed by the proxy. *

* If the receiver implements the interface then the result is the receiver or a proxy for the receiver. If the * receiver is a wrapper and the wrapped object implements the interface then the result is the wrapped object or a * proxy for the wrapped object. Otherwise return the the result of calling unwrap recursively on the * wrapped object or a proxy for that result. If the receiver is not a wrapper and does not implement the interface, * then an SQLException is thrown. * * @param iface A Class defining an interface that the result must implement. * @return an object that implements the interface. May be a proxy for the actual implementing object. * @throws java.sql.SQLException If no object found that implements the interface * @since 1.6 */ public T unwrap(final Class iface) throws SQLException { return iface.cast(this); } /** * Returns true if this either implements the interface argument or is directly or indirectly a wrapper for an * object that does. Returns false otherwise. If this implements the interface then return true, else if this is a * wrapper then return the result of recursively calling isWrapperFor on the wrapped object. If this * does not implement the interface and is not a wrapper, return false. This method should be implemented as a * low-cost operation compared to unwrap so that callers can use this method to avoid expensive * unwrap calls that may fail. If this method returns true then calling unwrap with the * same argument should succeed. * * @param iface a Class defining an interface. * @return true if this implements the interface or directly or indirectly wraps an object that does. * @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper for an object with * the given interface. * @since 1.6 */ public boolean isWrapperFor(final Class iface) throws SQLException { return iface.isInstance(this); } /** * returns the username for the connection. * * @return the username. */ public String getUsername() { return protocol.getUsername(); } /** * returns the password for the connection. * * @return the password. */ public String getPassword() { return protocol.getPassword(); } /** * returns the hostname for the connection. * * @return the hostname. */ public String getHostname() { return protocol.getHost(); } /** * returns the port for the connection. * * @return the port */ public int getPort() { return protocol.getPort(); } /** * returns the database. * * @return the database */ public String getDatabase() { return protocol.getDatabase(); } /** * returns a list of binlog entries. * * @param position the position to start at * @param logfile the log file to use * @return a list of rawpackets from the server * @throws SQLException if there is a problem talking to the server. */ public List startBinlogDump(final int position, final String logfile) throws SQLException { try { return this.protocol.startBinlogDump(position, logfile); } catch (BinlogDumpException e) { throw SQLExceptionMapper.getSQLException("Could not dump binlog", e); } } public void setBatchQueryHandlerFactory(final ParameterizedBatchHandlerFactory batchHandlerFactory) { this.parameterizedBatchHandlerFactory = batchHandlerFactory; } protected ScheduledExecutorService getTimeoutExecutor() { return timeoutExecutor; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy