/* * (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.Array; import java.sql.Blob; import java.sql.CallableStatement; import java.sql.Clob; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.NClob; import java.sql.PreparedStatement; import java.sql.SQLClientInfoException; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.SQLXML; import java.sql.Savepoint; import java.sql.Statement; import java.sql.Struct; import java.util.Map; import java.util.Properties; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import com.ibm.gaiandb.Logger; import com.ibm.gaiandb.diags.GDBMessages; import com.ibm.gaiandb.udpdriver.common.SocketHelper; import com.ibm.gaiandb.udpdriver.common.protocol.Message; /** * Implementation of java.sql.Connection * * @author lengelle * */ public class UDPConnection implements Connection { // 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( "UDPConnection", 25 ); //Query Id management. private static int QUERY_COUNTER = 0; private static int QUERY_COUNTER_MODULUS = 50000; /** * Returns a unique String ID. * @return */ static synchronized public String createQueryID() { QUERY_COUNTER = QUERY_COUNTER+1 % QUERY_COUNTER_MODULUS; return ""+QUERY_COUNTER+System.currentTimeMillis(); } /** * The server address */ private InetAddress serverAddress; /** * The server port */ private int serverPort; /** * The concurrent structure that contains the incoming messages for each query */ private ConcurrentMap< String, BlockingQueue<Message> > map; private ClientListener listener; private SocketHelper clientSocket; /** * Creates a new UDPConnection objects. * It represents a connection between the client which has instantiated this object and a * distant server, specified by the parameters serverAddress and serverPort. * * This instantiates and starts a new ClientListener. * This instantiates a new concurrent structure shared by the ClientListener and the * future Statement and PreparedStatement objects this Connection could generate. * * @param serverAddress the address of the distant server * @param serverPort the port of the distant server * @throws SQLException */ public UDPConnection( String serverAddress, String serverPort ) throws SQLException { try { this.serverAddress = InetAddress.getByName( serverAddress ); this.serverPort = Integer.decode( serverPort ); map = new ConcurrentHashMap< String, BlockingQueue<Message> >(); clientSocket = new SocketHelper(); listener = new ClientListener( clientSocket, map ); listener.start(); } catch( Exception e ) { throw new SQLException( "UDPConnection instantiation failed(). "+ e ); } } /** * Return the concurrent structure * @return */ public ConcurrentMap< String, BlockingQueue<Message> > getMap() { return map; } /* (non-Javadoc) * @see java.sql.Connection#createStatement() */ public Statement createStatement() throws SQLException { return new UDPStatement( this ); } /* (non-Javadoc) * @see java.sql.Connection#prepareStatement(java.lang.String) */ public PreparedStatement prepareStatement( String sql ) throws SQLException { return new UDPPreparedStatement( this, sql ); } /* (non-Javadoc) * @see java.sql.Connection#close() */ public synchronized void close() throws SQLException { try { if ( map==null ) { return; } SocketHelper sh = new SocketHelper(); sh.send( ClientListener.STOP_MESSAGE, InetAddress.getLocalHost(), clientSocket.getLocalPort() ); sh.close(); map = null; clientSocket = null; serverAddress = null; serverPort = -1; } catch( Exception e ) { throw new SQLException( "UDPConnection close() failed. "+ e ); } } /** * Return the address of the server this connection is bound to * @return */ public InetAddress getAddress() { return serverAddress; } /** * Return the port of the server this connection is bound to * @return */ public int getPort() { return serverPort; } /* (non-Javadoc) * @see java.sql.Connection#isClosed() */ public boolean isClosed() throws SQLException { return ( map == null ); } /** * Sends the message given as a parameter to the server. * * @param message * @throws SQLException */ public void sendMessage( byte[] message ) throws SQLException { try { if ( message.length > UDPDriver.DATAGRAM_SIZE ) { logger.logWarning( GDBMessages.NETDRIVER_MESSAGE_TOO_LONG, "A message longer than the current datagram size has been sent. Message type : " + message[0] ); } // System.out.println("Sending to serverAddress " + serverAddress + ", port " + serverPort + ", message: " + new String(message)); clientSocket.send( message, serverAddress, serverPort ); } catch( Exception e ) { throw new SQLException( "UDPConnection sendMessage() failed. "+ e ); } } /** * Helper method used by the Statement and PreparedStatement. * It tries to return a message from the map having the expected queryID, sequenceNumber and type * before the timeout exceeds. * If no message is found or received during this time, it returns null. * * @param queryID * @param sequenceNumberExpected * @param typeExpected * @param timeout * @return * @throws UDPDriverClientException */ public Message retreiveMessageFromMap( String queryID, int sequenceNumberExpected, int typeExpected, long timeout ) throws UDPDriverClientException { try { Message m = map.get( queryID ).poll( timeout, TimeUnit.MILLISECONDS ); while ( m!=null && ( m.getSequenceNumber()!=sequenceNumberExpected || m.getType()!=typeExpected ) ) { logger.logWarning(GDBMessages.NETDRIVER_MESSAGE_CONTAINS_UNWANTED_TYPES, "Throwing away message containing unwanted " + ( m.getType()!=typeExpected ? "type: " + m.getType() + " != expected: " + typeExpected : "sequence number: " + m.getSequenceNumber() + " != expected: " + sequenceNumberExpected ) ); m = map.get( queryID ).poll( timeout, TimeUnit.MILLISECONDS ); } return m; } catch( Exception e ) { throw new UDPDriverClientException( "UDPConnection getMessage() failed. ", e ); } } public void clearWarnings() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "clearWarnings() : Unimplemented method." ); } public void commit() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "commit() : Unimplemented method." ); } public Array createArrayOf( String typeName, Object[] elements ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createArrayOf( String typeName, Object[] elements ) : Unimplemented method." ); return null ; } public Blob createBlob() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createBlob() : Unimplemented method." ); return null ; } public Clob createClob() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createClob() : Unimplemented method." ); return null ; } public NClob createNClob() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createNClob() : Unimplemented method." ); return null ; } public SQLXML createSQLXML() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createSQLXML() : Unimplemented method." ); return null ; } public Statement createStatement( int resultSetType, int resultSetConcurrency ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createStatement( int resultSetType, int resultSetConcurrency ) : Unimplemented method." ); return null ; } public Statement createStatement( int resultSetType, int resultSetConcurrency, int resultSetHoldability ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createStatement( int resultSetType, int resultSetConcurrency, int resultSetHoldability ) : Unimplemented method." ); return null ; } public Struct createStruct( String typeName, Object[] attributes ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "createStruct( String typeName, Object[] attributes ) : Unimplemented method." ); return null ; } public boolean getAutoCommit() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getAutoCommit() : Unimplemented method." ); return false ; } public String getCatalog() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getCatalog() : Unimplemented method." ); return null ; } public Properties getClientInfo() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getClientInfo() : Unimplemented method." ); return null ; } public String getClientInfo( String name ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getClientInfo( String name ) : Unimplemented method." ); return null ; } public int getHoldability() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getHoldability() : Unimplemented method." ); return 0 ; } public DatabaseMetaData getMetaData() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getMetaData() : Unimplemented method." ); return null ; } public int getTransactionIsolation() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getTransactionIsolation() : Unimplemented method." ); return 0 ; } public Map<String, Class<?>> getTypeMap() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getTypeMap() : Unimplemented method." ); return null ; } public SQLWarning getWarnings() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getWarnings() : Unimplemented method." ); return null ; } public boolean isReadOnly() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "isReadOnly() : Unimplemented method." ); return false ; } public boolean isValid( int timeout ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "isValid( int timeout ) : Unimplemented method." ); return false ; } public String nativeSQL( String sql ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "nativeSQL( String sql ) : Unimplemented method." ); return null ; } public CallableStatement prepareCall( String sql ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareCall( String sql ) : Unimplemented method." ); return null ; } public CallableStatement prepareCall( String sql, int resultSetType, int resultSetConcurrency ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareCall( String sql, int resultSetType, int resultSetConcurrency ) : Unimplemented method." ); return null ; } public CallableStatement prepareCall( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareCall( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability ) : Unimplemented method." ); return null ; } public PreparedStatement prepareStatement( String sql, int autoGeneratedKeys ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareStatement( String sql, int autoGeneratedKeys ) : Unimplemented method." ); return null ; } public PreparedStatement prepareStatement( String sql, int[] columnIndexes ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareStatement( String sql, int[] columnIndexes ) : Unimplemented method." ); return null ; } public PreparedStatement prepareStatement( String sql, String[] columnNames ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareStatement( String sql, String[] columnNames ) : Unimplemented method." ); return null ; } public PreparedStatement prepareStatement( String sql, int resultSetType, int resultSetConcurrency ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareStatement( String sql, int resultSetType, int resultSetConcurrency ) : Unimplemented method." ); return null ; } public PreparedStatement prepareStatement( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "prepareStatement( String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability ) : Unimplemented method." ); return null ; } public void releaseSavepoint( Savepoint savepoint ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "releaseSavepoint( Savepoint savepoint ) : Unimplemented method." ); } public void rollback() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "rollback() : Unimplemented method." ); } public void rollback( Savepoint savepoint ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "rollback( Savepoint savepoint ) : Unimplemented method." ); } public void setAutoCommit( boolean autoCommit ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setAutoCommit( boolean autoCommit ) : Unimplemented method." ); } public void setCatalog( String catalog ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setCatalog( String catalog ) : Unimplemented method." ); } public void setClientInfo( Properties properties ) throws SQLClientInfoException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setClientInfo( Properties properties ) : Unimplemented method." ); } public void setClientInfo( String name, String value ) throws SQLClientInfoException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setClientInfo( String name, String value ) : Unimplemented method." ); } public void setHoldability( int holdability ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setHoldability( int holdability ) : Unimplemented method." ); } public void setReadOnly( boolean readOnly ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setReadOnly( boolean readOnly ) : Unimplemented method." ); } public Savepoint setSavepoint() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setSavepoint() : Unimplemented method." ); return null ; } public Savepoint setSavepoint( String name ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setSavepoint( String name ) : Unimplemented method." ); return null ; } public void setTransactionIsolation( int level ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setTransactionIsolation( int level ) : Unimplemented method." ); } public void setTypeMap( Map<String, Class<?>> map ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setTypeMap( Map<String, Class<?>> map ) : Unimplemented method." ); } public boolean isWrapperFor( Class<?> iface ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "isWrapperFor( Class<?> iface ) : Unimplemented method." ); return false ; } public <T> T unwrap( Class<T> iface ) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "unwrap( Class<T> iface ) : Unimplemented method." ); return null ; } public void abort(Executor executor) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "abort(Executor executor) : Unimplemented method." ); } public int getNetworkTimeout() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getNetworkTimeout() : Unimplemented method." ); return 0; } public String getSchema() throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "getSchema() : Unimplemented method." ); return null; } public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setNetworkTimeout(Executor executor, int milliseconds) : Unimplemented method." ); } public void setSchema(String schema) throws SQLException { logger.logWarning( GDBMessages.NETDRIVER_UNIMPLEMENTED_METHOD, "setSchema(String schema) : Unimplemented method." ); } }