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

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

The 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.Protocol;
import org.drizzle.jdbc.internal.common.QueryException;
import org.drizzle.jdbc.internal.common.query.Query;
import org.drizzle.jdbc.internal.common.query.QueryFactory;
import org.drizzle.jdbc.internal.common.queryresults.ModifyQueryResult;
import org.drizzle.jdbc.internal.common.queryresults.QueryResult;
import org.drizzle.jdbc.internal.common.queryresults.ResultSetType;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

/**
 * A sql statement.
 * 

* User: marcuse Date: Jan 19, 2009 Time: 10:10:58 PM */ public class DrizzleStatement implements Statement { /** * the protocol used to talk to the server. */ private final Protocol protocol; /** * the result set produced by execute(). */ private ResultSet resultSet; /** * how many rows were updated. */ private long updateCount; /** * the sql Connection object. */ private final DrizzleConnection connection; /** * The actual query result. */ private QueryResult queryResult; /** * are warnings cleared? */ private boolean warningsCleared; /** * creates queries. */ private final QueryFactory queryFactory; private InputStream inputStream; private int queryTimeout; private ScheduledFuture timoutFuture; /** * Creates a new Statement. * * @param protocol the protocol to use. * @param connection the connection to return in getConnection. * @param queryFactory the query factory to produce internal queries. */ public DrizzleStatement(final Protocol protocol, final DrizzleConnection connection, final QueryFactory queryFactory) { this.protocol = protocol; this.connection = connection; this.queryFactory = queryFactory; } /** * returns the protocol. * * @return the protocol used. */ public Protocol getProtocol() { return protocol; } /** * executes a select query. * * @param query the query to send to the server * @return a result set * @throws SQLException if something went wrong */ public ResultSet executeQuery(final String query) throws SQLException { startTimer(); try { if (queryResult != null) { queryResult.close(); } final Query queryToSend = queryFactory.createQuery(query); queryResult = protocol.executeQuery(queryToSend); warningsCleared = false; return new DrizzleResultSet(queryResult, this, getProtocol()); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } finally { stopTimer(); } } protected void startTimer() { if(this.queryTimeout > 0) { this.timoutFuture = this.connection.getTimeoutExecutor().schedule(new Runnable() { public void run() { try { getProtocol().timeOut(); } catch (QueryException e) { throw new RuntimeException("Could not time out query.", e); } } }, queryTimeout, TimeUnit.SECONDS); } } protected void stopTimer() { if(this.timoutFuture != null && !this.timoutFuture.isDone()) { this.timoutFuture.cancel(true); } } /** * Executes an update. * * @param query the update query. * @return update count * @throws SQLException if the query could not be sent to server. */ public int executeUpdate(final String query) throws SQLException { startTimer(); try { if (queryResult != null) { queryResult.close(); } warningsCleared = false; if(inputStream == null) queryResult = protocol.executeQuery(queryFactory.createQuery(query)); else queryResult = protocol.executeQuery(queryFactory.createQuery(query), inputStream); return (int) ((ModifyQueryResult) queryResult).getUpdateCount(); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } finally { stopTimer(); if(inputStream != null) { try { inputStream.close(); } catch (IOException e) { } inputStream = null; } } } /** * executes a query. * * @param query the query * @return true if there was a result set, false otherwise. * @throws SQLException */ public boolean execute(final String query) throws SQLException { startTimer(); try { if (queryResult != null) { queryResult.close(); } queryResult = protocol.executeQuery(queryFactory.createQuery(query)); if (queryResult.getResultSetType() == ResultSetType.SELECT) { setResultSet(new DrizzleResultSet(queryResult, this, getProtocol())); return true; } setUpdateCount(((ModifyQueryResult) queryResult).getUpdateCount()); return false; } catch (QueryException e) { throw SQLExceptionMapper.get(e); } finally { stopTimer(); } } public QueryFactory getQueryFactory() { return queryFactory; } /** * Releases this Statement object's database and JDBC resources immediately instead of waiting for this * to happen when it is automatically closed. It is generally good practice to release resources as soon as you are * finished with them to avoid tying up database resources. *

* Calling the method close on a Statement object that is already closed has no effect. *

* Note:When a Statement object is closed, its current ResultSet object, if one * exists, is also closed. * * @throws java.sql.SQLException if a database access error occurs */ public void close() throws SQLException { if (queryResult != null) { queryResult.close(); } } /** * Retrieves the maximum number of bytes that can be returned for character and binary column values in a * ResultSet object produced by this Statement object. This limit applies only to * BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, * NCHAR, NVARCHAR, LONGNVARCHAR and LONGVARCHAR columns. If * the limit is exceeded, the excess data is silently discarded. * * @return the current column size limit for columns storing character and binary values; zero means there is no * limit * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @see #setMaxFieldSize */ public int getMaxFieldSize() throws SQLException { return 0; } /** * Sets the limit for the maximum number of bytes that can be returned for character and binary column values in a * ResultSet object produced by this Statement object. *

* This limit applies only to BINARY, VARBINARY, LONGVARBINARY, * CHAR, VARCHAR, NCHAR, NVARCHAR, LONGNVARCHAR and * LONGVARCHAR fields. If the limit is exceeded, the excess data is silently discarded. For maximum * portability, use values greater than 256. * * @param max the new column size limit in bytes; zero means there is no limit * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the condition max >= 0 is not satisfied * @see #getMaxFieldSize */ public void setMaxFieldSize(final int max) throws SQLException { //we dont support max field sizes } /** * Retrieves the maximum number of rows that a ResultSet object produced by this Statement * object can contain. If this limit is exceeded, the excess rows are silently dropped. * * @return the current maximum number of rows for a ResultSet object produced by this * Statement object; zero means there is no limit * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @see #setMaxRows */ public int getMaxRows() throws SQLException { return 0; // 0 = no limit } /** * Sets the limit for the maximum number of rows that any ResultSet object generated by this * Statement object can contain to the given number. If the limit is exceeded, the excess rows are * silently dropped. * * @param max the new max rows limit; zero means there is no limit * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the condition max >= 0 is not satisfied * @see #getMaxRows */ public void setMaxRows(final int max) throws SQLException { //we dont support this (yet?) } /** * Sets escape processing on or off. If escape scanning is on (the default), the driver will do escape substitution * before sending the SQL statement to the database. *

* Note: Since prepared statements have usually been parsed prior to making this call, disabling escape processing * for PreparedStatements objects will have no effect. * * @param enable true to enable escape processing; false to disable it * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement */ public void setEscapeProcessing(final boolean enable) throws SQLException { //TODO: check jdbc4 docs for more info } /** * Retrieves the number of seconds the driver will wait for a Statement object to execute. If the limit * is exceeded, a SQLException is thrown. * * @return the current query timeout limit in seconds; zero means there is no limit * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @see #setQueryTimeout */ public int getQueryTimeout() throws SQLException { return queryTimeout; } /** * Sets the number of seconds the driver will wait for a Statement object to execute to the given * number of seconds. If the limit is exceeded, an SQLException is thrown. A JDBC driver must apply * this limit to the execute, executeQuery and executeUpdate methods. JDBC * driver implementations may also apply this limit to ResultSet methods (consult your driver vendor * documentation for details). * * @param seconds the new query timeout limit in seconds; zero means there is no limit * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the condition seconds >= 0 is not satisfied * @see #getQueryTimeout */ public void setQueryTimeout(final int seconds) throws SQLException { this.queryTimeout = seconds; } /** * Cancels this Statement object if both the DBMS and driver support aborting an SQL statement. This * method can be used by one thread to cancel a statement that is being executed by another thread. * * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method */ public void cancel() throws SQLException { try { protocol.cancelCurrentQuery(); } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * Retrieves the first warning reported by calls on this Statement object. Subsequent * Statement object warnings will be chained to this SQLWarning object. *

*

The warning chain is automatically cleared each time a statement is (re)executed. This method may not be * called on a closed Statement object; doing so will cause an SQLException to be thrown. *

*

Note: If you are processing a ResultSet object, any warnings associated with reads on that * ResultSet object will be chained on it rather than on the Statement object that * produced it. * * @return the first SQLWarning object or null if there are no warnings * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement */ public SQLWarning getWarnings() throws SQLException { if (!warningsCleared && queryResult != null && queryResult.getWarnings() > 0) { return new SQLWarning(queryResult.getMessage()); } return null; } /** * Clears all the warnings reported on this Statement object. After a call to this method, the method * getWarnings will return null until a new warning is reported for this * Statement object. * * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement */ public void clearWarnings() throws SQLException { warningsCleared = true; } /** * Sets the SQL cursor name to the given String, which will be used by subsequent * Statement object execute methods. This name can then be used in SQL positioned update * or delete statements to identify the current row in the ResultSet object generated by this * statement. If the database does not support positioned update/delete, this method is a noop. To insure that a * cursor has the proper isolation level to support updates, the cursor's SELECT statement should have * the form SELECT FOR UPDATE. If FOR UPDATE is not present, positioned updates may * fail. *

*

Note: By definition, the execution of positioned updates and deletes must be done by a different * Statement object than the one that generated the ResultSet object being used for * positioning. Also, cursor names must be unique within a connection. * * @param name the new cursor name, which must be unique within a connection * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method */ public void setCursorName(final String name) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Cursors are not supported"); } /** * gets the connection that created this statement * * @return the connection * @throws SQLException */ public Connection getConnection() throws SQLException { return this.connection; } /** * Moves to this Statement object's next result, deals with any current ResultSet * object(s) according to the instructions specified by the given flag, and returns true if the next * result is a ResultSet object. *

*

There are no more results when the following is true:

 // stmt is a Statement object
     * ((stmt.getMoreResults(current) == false) && (stmt.getUpdateCount() == -1)) 
* * @param current one of the following Statement constants indicating what should happen to current * ResultSet objects obtained using the method getResultSet: * Statement.CLOSE_CURRENT_RESULT, Statement.KEEP_CURRENT_RESULT, or * Statement.CLOSE_ALL_RESULTS * @return true if the next result is a ResultSet object; false if it is an * update count or there are no more results * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the argument supplied is not one of the following: * Statement.CLOSE_CURRENT_RESULT, Statement.KEEP_CURRENT_RESULT * or Statement.CLOSE_ALL_RESULTS * @throws java.sql.SQLFeatureNotSupportedException * if DatabaseMetaData.supportsMultipleOpenResults returns * false and either Statement.KEEP_CURRENT_RESULT or * Statement.CLOSE_ALL_RESULTS are supplied as the argument. * @see #execute * @since 1.4 */ public boolean getMoreResults(final int current) throws SQLException { return getMoreResults(); } /** * Retrieves any auto-generated keys created as a result of executing this Statement object. If this * Statement object did not generate any keys, an empty ResultSet object is returned. *

*

Note:If the columns which represent the auto-generated keys were not specified, the JDBC driver * implementation will determine the columns which best represent the auto-generated keys. * * @return a ResultSet object containing the auto-generated key(s) generated by the execution of this * Statement object * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ public ResultSet getGeneratedKeys() throws SQLException { if (queryResult != null && queryResult.getResultSetType() == ResultSetType.MODIFY) { final QueryResult genRes = ((ModifyQueryResult) queryResult).getGeneratedKeysResult(); return new DrizzleResultSet(genRes, this, getProtocol()); } return DrizzleResultSet.EMPTY; } /** * Executes the given SQL statement and signals the driver with the given flag about whether the auto-generated keys * produced by this Statement object should be made available for retrieval. The driver will ignore * the flag 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). * * @param sql an SQL Data Manipulation Language (DML) statement, such as INSERT, * UPDATE or DELETE; or an SQL statement that returns nothing, * such as a DDL statement. * @param autoGeneratedKeys a flag indicating whether auto-generated keys should be made available for retrieval; * one of the following constants: Statement.RETURN_GENERATED_KEYS * Statement.NO_GENERATED_KEYS * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements * that return nothing * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement, the given SQL statement returns a ResultSet * object, or the given constant is not one of those allowed * @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 int executeUpdate(final String sql, final int autoGeneratedKeys) throws SQLException { return executeUpdate(sql); } /** * Executes the given SQL statement and signals the driver that the auto-generated keys indicated in the given array * should be made available for retrieval. 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). * * @param sql an SQL Data Manipulation Language (DML) statement, such as INSERT, * UPDATE or DELETE; or an SQL statement that returns nothing, such * as a DDL statement. * @param columnIndexes an array of column indexes indicating the columns that should be returned from the inserted * row * @return either (1) the row count for SQL Data Manipulation Language (DML) statements or (2) 0 for SQL statements * that return nothing * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement, the SQL statement returns a ResultSet object, * or the second argument supplied to this method is not an int array * whose elements are valid column indexes * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ public int executeUpdate(final String sql, final int[] columnIndexes) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not supported"); } /** * Executes the given SQL statement and signals the driver that the auto-generated keys indicated in the given array * should be made available for retrieval. This array contains the names 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). * * @param sql an SQL Data Manipulation Language (DML) statement, such as INSERT, * UPDATE or DELETE; or an SQL statement that returns nothing, such as * a DDL statement. * @param columnNames an array of the names of the columns that should be returned from the inserted row * @return either the row count for INSERT, UPDATE, or DELETE statements, or * 0 for SQL statements that return nothing * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement, the SQL statement returns a ResultSet object, * or the second argument supplied to this method is not a String array * whose elements are valid column names * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @since 1.4 */ public int executeUpdate(final String sql, final String[] columnNames) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not supported"); } /** * Executes the given SQL statement, which may return multiple results, and signals the driver that any * auto-generated keys should be made available for retrieval. The driver will ignore this signal 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). *

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

* The execute method executes an SQL statement and indicates the form of the first result. You must * then use the methods getResultSet or getUpdateCount to retrieve the result, and * getMoreResults to move to any subsequent result(s). * * @param sql any SQL statement * @param autoGeneratedKeys a constant indicating whether auto-generated keys should be made available for retrieval * using the method getGeneratedKeys; one of the following constants: * Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS * @return true if the first result is a ResultSet object; false if it is an * update count or there are no results * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the second parameter supplied to this method is not * Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS. * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method with a constant of * Statement.RETURN_GENERATED_KEYS * @see #getResultSet * @see #getUpdateCount * @see #getMoreResults * @see #getGeneratedKeys * @since 1.4 */ public boolean execute(final String sql, final int autoGeneratedKeys) throws SQLException { return execute(sql); // auto generated keys are always available } /** * Executes the given SQL statement, which may return multiple results, and signals the driver that the * auto-generated keys indicated in the given array should be made available for retrieval. 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). *

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

* The execute method executes an SQL statement and indicates the form of the first result. You must * then use the methods getResultSet or getUpdateCount to retrieve the result, and * getMoreResults to move to any subsequent result(s). * * @param sql any SQL statement * @param columnIndexes an array of the indexes of the columns in the inserted row that should be made available * for retrieval by a call to the method getGeneratedKeys * @return true if the first result is a ResultSet object; false if it is an * update count or there are no results * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the elements in the int array passed to this * method are not valid column indexes * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see #getResultSet * @see #getUpdateCount * @see #getMoreResults * @since 1.4 */ public boolean execute(final String sql, final int[] columnIndexes) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not supported"); } /** * Executes the given SQL statement, which may return multiple results, and signals the driver that the * auto-generated keys indicated in the given array should be made available for retrieval. This array contains the * names 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). *

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

* The execute method executes an SQL statement and indicates the form of the first result. You must * then use the methods getResultSet or getUpdateCount to retrieve the result, and * getMoreResults to move to any subsequent result(s). * * @param sql any SQL statement * @param columnNames an array of the names of the columns in the inserted row that should be made available for * retrieval by a call to the method getGeneratedKeys * @return true if the next result is a ResultSet object; false if it is an * update count or there are no more results * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the elements of the String array passed to * this method are not valid column names * @throws java.sql.SQLFeatureNotSupportedException * if the JDBC driver does not support this method * @see #getResultSet * @see #getUpdateCount * @see #getMoreResults * @see #getGeneratedKeys * @since 1.4 */ public boolean execute(final String sql, final String[] columnNames) throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Not supported"); } /** * Retrieves the result set holdability for ResultSet objects generated by this Statement * object. * * @return either 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 * Statement * @since 1.4 */ public int getResultSetHoldability() throws SQLException { return ResultSet.HOLD_CURSORS_OVER_COMMIT; } /** * Retrieves whether this Statement object has been closed. A Statement is closed if the * method close has been called on it, or if it is automatically closed. * * @return true if this Statement object is closed; false if it is still open * @throws java.sql.SQLException if a database access error occurs * @since 1.6 */ public boolean isClosed() throws SQLException { return false; } /** * Requests that a Statement be pooled or not pooled. The value specified is a hint to the statement * pool implementation indicating whether the applicaiton wants the statement to be pooled. It is up to the * statement pool manager as to whether the hint is used. *

* The poolable value of a statement is applicable to both internal statement caches implemented by the driver and * external statement caches implemented by application servers and other applications. *

* By default, a Statement is not poolable when created, and a PreparedStatement and * CallableStatement are poolable when created. *

* * @param poolable requests that the statement be pooled if true and that the statement not be pooled if false *

* @throws java.sql.SQLException if this method is called on a closed Statement *

* @since 1.6 */ public void setPoolable(final boolean poolable) throws SQLException { } /** * Returns a value indicating whether the Statement is poolable or not. *

* * @return true if the Statement is poolable; false otherwise *

* @throws java.sql.SQLException if this method is called on a closed Statement *

* @see java.sql.Statement#setPoolable(boolean) setPoolable(boolean) * @since 1.6 *

*/ public boolean isPoolable() throws SQLException { return false; } public ResultSet getResultSet() throws SQLException { return resultSet; } public int getUpdateCount() throws SQLException { if(queryResult != null && queryResult.getResultSetType() == ResultSetType.SELECT) { return -1; } return (int)updateCount; } /** * Moves to this Statement object's next result, returns true if it is a * ResultSet object, and implicitly closes any current ResultSet object(s) obtained with * the method getResultSet. *

*

There are no more results when the following is true:

 // stmt is a Statement object
     * ((stmt.getMoreResults() == false) && (stmt.getUpdateCount() == -1)) 
* * @return true if the next result is a ResultSet object; false if it is an * update count or there are no more results * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @see #execute */ public boolean getMoreResults() throws SQLException { startTimer(); try { if (queryResult != null) { queryResult.close(); } queryResult = protocol.getMoreResults(); if(queryResult == null) { this.resultSet=null; setUpdateCount(-1); return false; } warningsCleared = false; if (queryResult.getResultSetType() == ResultSetType.SELECT) { setResultSet(new DrizzleResultSet(queryResult, this, getProtocol())); return true; } setUpdateCount((int)((ModifyQueryResult) queryResult).getUpdateCount()); return false; } catch (QueryException e) { throw SQLExceptionMapper.get(e); } finally { stopTimer(); } } /** * Gives the driver a hint as to the direction in which rows will be processed in ResultSet objects * created using this Statement object. The default value is ResultSet.FETCH_FORWARD. *

* Note that this method sets the default fetch direction for result sets generated by this Statement * object. Each result set has its own methods for getting and setting its own fetch direction. * * @param direction the initial direction for processing rows * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the given direction is not one of * ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or * ResultSet.FETCH_UNKNOWN * @see #getFetchDirection * @since 1.2 */ public void setFetchDirection(final int direction) throws SQLException { } /** * Retrieves the direction for fetching rows from database tables that is the default for result sets generated from * this Statement object. If this Statement object has not set a fetch direction by * calling the method setFetchDirection, the return value is implementation-specific. * * @return the default fetch direction for result sets generated from this Statement object * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @see #setFetchDirection * @since 1.2 */ public int getFetchDirection() throws SQLException { return ResultSet.FETCH_FORWARD; } /** * Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are * needed for ResultSet objects genrated by this Statement. If the value specified is * zero, then the hint is ignored. The default value is zero. * * @param rows the number of rows to fetch * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the condition rows >= 0 is not satisfied. * @see #getFetchSize * @since 1.2 */ public void setFetchSize(final int rows) throws SQLException { } /** * Retrieves the number of result set rows that is the default fetch size for ResultSet objects * generated from this Statement object. If this Statement object has not set a fetch size * by calling the method setFetchSize, the return value is implementation-specific. * * @return the default fetch size for result sets generated from this Statement object * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @see #setFetchSize * @since 1.2 */ public int getFetchSize() throws SQLException { return 0; } /** * Retrieves the result set concurrency for ResultSet objects generated by this Statement * object. * * @return either ResultSet.CONCUR_READ_ONLY or ResultSet.CONCUR_UPDATABLE * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @since 1.2 */ public int getResultSetConcurrency() throws SQLException { return ResultSet.CONCUR_READ_ONLY; } /** * Retrieves the result set type for ResultSet objects generated by this Statement * object. * * @return one of ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_SCROLL_INSENSITIVE, or * ResultSet.TYPE_SCROLL_SENSITIVE * @throws java.sql.SQLException if a database access error occurs or this method is called on a closed * Statement * @since 1.2 */ public int getResultSetType() throws SQLException { // TODO: this will change when the async protocol is implemented return ResultSet.TYPE_SCROLL_INSENSITIVE; } /** * Adds the given SQL command to the current list of commmands for this Statement object. The commands * in this list can be executed as a batch by calling the method executeBatch. *

* * @param sql typically this is a SQL INSERT or UPDATE statement * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the driver does not support batch updates * @see #executeBatch * @see java.sql.DatabaseMetaData#supportsBatchUpdates * @since 1.2 */ public void addBatch(final String sql) throws SQLException { this.protocol.addToBatch(queryFactory.createQuery(sql)); } public void addBatch(final byte[] sql) throws SQLException { this.protocol.addToBatch(queryFactory.createQuery(sql)); } /** * Empties this Statement object's current list of SQL commands. *

* * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the driver does not support batch updates * @see #addBatch * @see java.sql.DatabaseMetaData#supportsBatchUpdates * @since 1.2 */ public void clearBatch() throws SQLException { this.protocol.clearBatch(); } /** * Submits a batch of commands to the database for execution and if all commands execute successfully, returns an * array of update counts. The int elements of the array that is returned are ordered to correspond to * the commands in the batch, which are ordered according to the order in which they were added to the batch. The * elements in the array returned by the method executeBatch may be one of the following:

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

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

    *

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

* The possible implementations and return values have been modified in the Java 2 SDK, Standard Edition, version * 1.3 to accommodate the option of continuing to proccess commands in a batch update after a * BatchUpdateException obejct has been thrown. * * @return an array of update counts containing one element for each command in the batch. The elements of the * array are ordered according to the order in which commands were added to the batch. * @throws java.sql.SQLException if a database access error occurs, this method is called on a closed * Statement or the driver does not support batch statements. Throws * {@link java.sql.BatchUpdateException} (a subclass of SQLException) if * one of the commands sent to the database fails to execute properly or attempts to * return a result set. * @see #addBatch * @see java.sql.DatabaseMetaData#supportsBatchUpdates * @since 1.3 */ public int[] executeBatch() throws SQLException { try { final List queryRes = protocol.executeBatch(); final int[] retVals = new int[queryRes.size()]; int i = 0; for (final QueryResult qr : queryRes) { if (qr.getResultSetType() == ResultSetType.MODIFY) { retVals[i++] = (int) ((ModifyQueryResult) qr).getUpdateCount(); //TODO: this needs to be handled according to javadoc } else { retVals[i++] = SUCCESS_NO_INFO; } } return retVals; } catch (QueryException e) { throw SQLExceptionMapper.get(e); } } /** * 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 null; } /** * 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 false; } protected void setResultSet(final DrizzleResultSet drizzleResultSet) { this.resultSet = drizzleResultSet; } protected void setUpdateCount(final long updateCount) { this.updateCount = updateCount; } /** * returns the query result. * * @return the queryresult */ protected QueryResult getQueryResult() { return queryResult; } /** * sets the current query result * * @param result */ protected void setQueryResult(final QueryResult result) { this.queryResult = result; } public void setLocalInfileInputStream(InputStream is) { this.inputStream = is; } /** * Indicates whether the statement is auto-closed when no result sets are * remain open. * * @return True or false. */ public boolean isCloseOnCompletion() throws SQLException { return false; } public void closeOnCompletion() throws SQLException { throw SQLExceptionMapper.getFeatureNotSupportedException("Statement closeOnCompletion"); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy