/* * (C) Copyright IBM Corp. 2010 * * LICENSE: Eclipse Public License v1.0 * http://www.eclipse.org/legal/epl-v10.html */ package com.ibm.gaiandb.udpdriver.client; import java.net.InetAddress; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Statement; import java.util.concurrent.ArrayBlockingQueue; import com.ibm.gaiandb.GaianDBConfig; import com.ibm.gaiandb.Logger; import com.ibm.gaiandb.udpdriver.common.protocol.Message; import com.ibm.gaiandb.udpdriver.common.protocol.MessageFactory; import com.ibm.gaiandb.udpdriver.common.protocol.MetaData; import com.ibm.gaiandb.udpdriver.common.protocol.QueryRequest; /** * Implementation of java.sql.Driver * * @author lengelle * */ public class UDPStatement implements Statement { // Use PROPRIETARY notice if class contains a main() method, otherwise use COPYRIGHT notice. public static final String COPYRIGHT_NOTICE = "(c) Copyright IBM Corp. 2010"; private static final Logger logger = new Logger( "UDPStatement", 25 ); protected static final int BLOCKING_QUEUE_MAX_SIZE = 5; protected UDPConnection connection; protected String queryID; protected int messageSequenceNumber; protected long adaptiveTimeout; protected UDPResultSet resultSet; protected UDPResultSetMetaData resultSetMetaData; /** * Instantiates a UDPStatement object. * * @param connection UDPConnection object that produced this statement * @throws SQLException */ public UDPStatement( UDPConnection connection ) throws SQLException { this.connection = connection; this.queryID = ""; messageSequenceNumber = -1; this.resultSet = null; this.resultSetMetaData = null; } /* (non-Javadoc) * @see java.sql.Statement#executeQuery(java.lang.String) */ public ResultSet executeQuery( String sql ) throws SQLException { try { queryID = createQueryId(); messageSequenceNumber = 0; createNewEntryInMap(); // Send the query QueryRequest queryRequest = MessageFactory.getQueryRequestMessage( queryID ); queryRequest.setSequenceNumber( messageSequenceNumber ); queryRequest.setStatementType( Message.STATEMENT ); queryRequest.setQuery( sql ); MetaData metaData = sendQueryRequestAndReturnMetaData( queryRequest ); resultSetMetaData = new UDPResultSetMetaData( metaData ); MessageFactory.returnMessage( queryRequest ); // We can't recycle the previous UDPResultSet object because it is link to the previous // meta-data. Between two execution of executeQuery(), the meta-data could have changed. if ( resultSet != null ) { resultSet.clean(); resultSet = null; } resultSet = new UDPResultSet( resultSetMetaData, this, metaData ); return resultSet; } catch( Exception e ) { throw new SQLException( "UDPStatement : executeQuery() failed. "+ e ); } } /** * * Sends a QueryRequest to the server. * Waits for the response MetaData and returns it if received. * Else considers that a datagram was lost and throws an exception. * * The timeout used for this round trip is : UDPDriver.FIRST_TIMEOUT. * If successful, the new timeout will be the time taken by this round trip + UDPDriver.MARGIN_TIMEOUT. * * @param queryRequest * @return * @throws SQLException */ protected MetaData sendQueryRequestAndReturnMetaData( QueryRequest queryRequest ) throws SQLException { try { // Send the query long clock1 = System.currentTimeMillis(); connection.sendMessage( queryRequest.serializeMessage() ); // Wait for the first response : the Meta-Data Message message = connection.retreiveMessageFromMap( queryID, ++messageSequenceNumber, Message.META_DATA, getQueryTimeout()*1000) ; //UDPDriver.FIRST_TIMEOUT ); if ( message == null ) { throw new SQLException( "Datagram lost on initial query execution !" ); } MetaData metaData = ( MetaData )message; long clock2 = System.currentTimeMillis(); adaptiveTimeout = ( clock2 - clock1 ) + UDPDriver.TIMEOUT_MARGIN; return metaData; } catch( Exception e ) { throw new SQLException( e.getMessage() ); } } public InetAddress getServerAddress() { return connection.getAddress(); } public int getServerPort() { return connection.getPort(); } protected String createQueryId() { return UDPConnection.createQueryID(); } /** * Creates a new entry in the concurrent structure provided by the UDPConnection. * The key of this new entry is the queryID. * * @throws SQLException */ protected void createNewEntryInMap() throws SQLException { if ( connection.getMap().containsKey( queryID ) ) { throw new SQLException( "UDPStatement : createNewEntryInMap() Map already contains the key." ); } connection.getMap().put( queryID , new ArrayBlockingQueue<Message>( BLOCKING_QUEUE_MAX_SIZE ) ); } /* (non-Javadoc) * @see java.sql.Statement#close() */ public void close() throws SQLException { if ( connection.getMap()!= null && queryID != null ) { connection.getMap().remove( queryID ); } if ( resultSet != null ) { resultSet.close(); resultSet.clean(); } resultSetMetaData = null; } /* (non-Javadoc) * @see java.sql.Statement#getConnection() */ public Connection getConnection() throws SQLException { return connection; } /** * Return the UDPConnection object that produced this Statement object. * * @return */ public UDPConnection getUDPConnection() { return connection; } /* (non-Javadoc) * @see java.sql.Statement#getResultSet() */ public ResultSet getResultSet() throws SQLException { return resultSet; } public long getAdaptiveTimeout() { return adaptiveTimeout; } public void setAdaptiveTimeout( long adaptiveTimeout ) { this.adaptiveTimeout = adaptiveTimeout; } public int getUpdateCount() throws SQLException { // logger.logAlways( "UDPStatement getUpdateCount(): Unimplemented method." ); return -1; } public boolean getMoreResults() throws SQLException { return true; } public SQLWarning getWarnings() throws SQLException { // logger.logAlways( "UDPStatement getWarnings(): Unimplemented method." ); return null; } private int timeout = -1; //(int) (UDPDriver.FIRST_TIMEOUT/1000); public void setQueryTimeout( int seconds ) throws SQLException { // logger.logAlways( "UDPStatement setQueryTimeout( int seconds ): Unimplemented method." ); // if ( 5 < seconds ) timeout = seconds; } public int getQueryTimeout() throws SQLException { // logger.logAlways( "UDPStatement getQueryTimeout(): Unimplemented method." ); return -1 < timeout ? timeout : GaianDBConfig.getNetworkDriverGDBUDPTimeout()/1000; } public void addBatch( String sql ) throws SQLException { logger.logAlways( "UDPStatement addBatch( String sql ): Unimplemented method ." ); } public void cancel() throws SQLException { logger.logAlways( "UDPStatement cancel(): Unimplemented method." ); } public void clearBatch() throws SQLException { logger.logAlways( "UDPStatement clearBatch(): Unimplemented method." ); } public void clearWarnings() throws SQLException { logger.logAlways( "UDPStatement clearWarnings(): Unimplemented method." ); } public boolean execute( String sql ) throws SQLException { logger.logAlways( "UDPStatement execute( String sql ): Unimplemented method." ); return false ; } public boolean execute( String sql, int autoGeneratedKeys ) throws SQLException { logger.logAlways( "UDPStatement execute( String sql, int autoGeneratedKeys ): Unimplemented method." ); return false ; } public boolean execute( String sql, int[] columnIndexes ) throws SQLException { logger.logAlways( "UDPStatement execute( String sql, int[] columnIndexes ): Unimplemented method." ); return false ; } public boolean execute( String sql, String[] columnNames ) throws SQLException { logger.logAlways( "UDPStatement execute( String sql, String[] columnNames ): Unimplemented method." ); return false ; } public int[] executeBatch() throws SQLException { logger.logAlways( "UDPStatement executeBatch(): Unimplemented method." ); return null ; } public int executeUpdate( String sql ) throws SQLException { logger.logAlways( "UDPStatement executeUpdate( String sql ): Unimplemented method." ); return 0 ; } public int executeUpdate( String sql, int autoGeneratedKeys ) throws SQLException { logger.logAlways( "UDPStatement executeUpdate( String sql, int autoGeneratedKeys ): Unimplemented method." ); return 0 ; } public int executeUpdate( String sql, int[] columnIndexes ) throws SQLException { logger.logAlways( "UDPStatement executeUpdate( String sql, int[] columnIndexes ): Unimplemented method." ); return 0 ; } public int executeUpdate( String sql, String[] columnNames ) throws SQLException { logger.logAlways( "UDPStatement executeUpdate( String sql, String[] columnNames ): Unimplemented method." ); return 0 ; } public int getFetchDirection() throws SQLException { logger.logAlways( "UDPStatement getFetchDirection(): Unimplemented method." ); return 0 ; } public int getFetchSize() throws SQLException { logger.logAlways( "UDPStatement getFetchSize(): Unimplemented method." ); return 0 ; } public ResultSet getGeneratedKeys() throws SQLException { logger.logAlways( "UDPStatement getGeneratedKeys(): Unimplemented method." ); return null ; } public int getMaxFieldSize() throws SQLException { logger.logAlways( "UDPStatement getMaxFieldSize(): Unimplemented method." ); return 0 ; } public int getMaxRows() throws SQLException { logger.logAlways( "UDPStatement getMaxRows(): Unimplemented method." ); return 0 ; } public boolean getMoreResults( int current ) throws SQLException { logger.logAlways( "UDPStatement getMoreResults( int current ): Unimplemented method." ); return false ; } public int getResultSetConcurrency() throws SQLException { logger.logAlways( "UDPStatement getResultSetConcurrency(): Unimplemented method." ); return 0 ; } public int getResultSetHoldability() throws SQLException { logger.logAlways( "UDPStatement getResultSetHoldability(): Unimplemented method." ); return 0 ; } public int getResultSetType() throws SQLException { logger.logAlways( "UDPStatement getResultSetType(): Unimplemented method." ); return 0 ; } public boolean isClosed() throws SQLException { logger.logAlways( "UDPStatement isClosed(): Unimplemented method." ); return false ; } public boolean isPoolable() throws SQLException { logger.logAlways( "UDPStatement isPoolable(): Unimplemented method." ); return false ; } public void setCursorName( String name ) throws SQLException { logger.logAlways( "UDPStatement setCursorName( String name ): Unimplemented method." ); } public void setEscapeProcessing( boolean enable ) throws SQLException { logger.logAlways( "UDPStatement setEscapeProcessing( boolean enable ): Unimplemented method." ); } public void setFetchDirection( int direction ) throws SQLException { logger.logAlways( "UDPStatement setFetchDirection( int direction ): Unimplemented method." ); } public void setFetchSize( int rows ) throws SQLException { logger.logAlways( "UDPStatement setFetchSize( int rows ): Unimplemented method." ); } public void setMaxFieldSize( int max ) throws SQLException { logger.logAlways( "UDPStatement setMaxFieldSize( int max ): Unimplemented method." ); } public void setMaxRows( int max ) throws SQLException { logger.logAlways( "UDPStatement setMaxRows( int max ): Unimplemented method." ); } public void setPoolable( boolean poolable ) throws SQLException { logger.logAlways( "UDPStatement setPoolable( boolean poolable ): Unimplemented method." ); } public boolean isWrapperFor( Class<?> iface ) throws SQLException { logger.logAlways( "UDPStatement isWrapperFor( Class<?> iface ): Unimplemented method." ); return false ; } public <T> T unwrap( Class<T> iface ) throws SQLException { logger.logAlways( "UDPStatement unwrap( Class<T> iface ): Unimplemented method." ); return null ; } public void closeOnCompletion() throws SQLException { logger.logAlways( "UDPStatement closeOnCompletion(): Unimplemented method." ); } public boolean isCloseOnCompletion() throws SQLException { logger.logAlways( "UDPStatement isCloseOnCompletion(): Unimplemented method." ); return false; } }