[teiid-commits] teiid SVN: r854 - in trunk/client-jdbc/src: test/java/com/metamatrix/jdbc and 1 other directory.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Fri May 1 10:18:00 EDT 2009


Author: loleary
Date: 2009-05-01 10:18:00 -0400 (Fri, 01 May 2009)
New Revision: 854

Added:
   trunk/client-jdbc/src/test/java/com/metamatrix/jdbc/TestMMPreparedStatement.java
Modified:
   trunk/client-jdbc/src/main/java/com/metamatrix/jdbc/MMPreparedStatement.java
Log:
TEIID-521: Added clearBatch() method to MMPreparedStatement to override method from MMStatement.
Fixed type-safety compiler warnings caused by the use of List without a type in MMPreparedStatement.
Reviewed By: rreddy

Modified: trunk/client-jdbc/src/main/java/com/metamatrix/jdbc/MMPreparedStatement.java
===================================================================
--- trunk/client-jdbc/src/main/java/com/metamatrix/jdbc/MMPreparedStatement.java	2009-04-30 21:31:54 UTC (rev 853)
+++ trunk/client-jdbc/src/main/java/com/metamatrix/jdbc/MMPreparedStatement.java	2009-05-01 14:18:00 UTC (rev 854)
@@ -95,7 +95,7 @@
     private Calendar serverCalendar;
 
     /**
-     * Factory Constuctor 
+     * Factory Constructor 
      * @param connection
      * @param sql
      * @param resultSetType
@@ -139,6 +139,18 @@
     }
 
     /**
+     * Makes the set of commands in the current batch empty.
+     *
+     * @throws SQLException if a database access error occurs or the
+     * driver does not support batch statements
+     */
+    public void clearBatch() throws SQLException {
+    	if (batchParameterList != null ) {
+    		batchParameterList.clear();
+    	}
+    }
+
+    /**
      * <p>Clears the values set for the PreparedStatement object's IN parameters and
      * releases the resources used by those values. In general, parameter values
      * remain in force for repeated use of statement.
@@ -545,11 +557,12 @@
             parameterMap = new TreeMap<Integer, Object>();
         }
         
+        Object val = null;
         if (serverCalendar != null && value instanceof java.util.Date) {
-            value = TimestampWithTimezone.create((java.util.Date)value, getDefaultCalendar().getTimeZone(), serverCalendar, value.getClass());
-        }
+            val = TimestampWithTimezone.create((java.util.Date)value, getDefaultCalendar().getTimeZone(), serverCalendar, value.getClass());
+        } else val = value;
 
-        parameterMap.put(new Integer(parameterIndex), value);
+        parameterMap.put(new Integer(parameterIndex), val);
     }
 
     /**
@@ -645,18 +658,18 @@
         setObject(parameterIndex, x);
     }
 
-    List getParameterValuesList() {
+    List<List<Object>> getParameterValuesList() {
     	if(batchParameterList == null || batchParameterList.isEmpty()){
-    		return Collections.EMPTY_LIST;
+    		return Collections.emptyList();
     	}
-    	return new ArrayList(batchParameterList);
+    	return new ArrayList<List<Object>>(batchParameterList);
     }
     
-    List getParameterValues() {
+    List<Object> getParameterValues() {
         if(parameterMap == null || parameterMap.isEmpty()){
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
-        return new ArrayList(parameterMap.values());
+        return new ArrayList<Object>(parameterMap.values());
     }
 
 	/* (non-Javadoc)

Added: trunk/client-jdbc/src/test/java/com/metamatrix/jdbc/TestMMPreparedStatement.java
===================================================================
--- trunk/client-jdbc/src/test/java/com/metamatrix/jdbc/TestMMPreparedStatement.java	                        (rev 0)
+++ trunk/client-jdbc/src/test/java/com/metamatrix/jdbc/TestMMPreparedStatement.java	2009-05-01 14:18:00 UTC (rev 854)
@@ -0,0 +1,340 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package com.metamatrix.jdbc;
+
+import static org.junit.Assert.*;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+import com.metamatrix.common.comm.api.ServerConnection;
+import com.metamatrix.dqp.client.ClientSideDQP;
+import com.metamatrix.dqp.client.ResultsFuture;
+import com.metamatrix.dqp.message.RequestMessage;
+import com.metamatrix.dqp.message.ResultsMessage;
+import com.metamatrix.platform.security.api.LogonResult;
+
+/**
+ * Test case to validate general operations on an <code>MMPreparedStatement
+ * </code> 
+ */
+public class TestMMPreparedStatement {
+
+	/**
+	 * Test that <code>MMPreparedStatement</code>'s <code>execute()</code> method
+	 * will throw a <code>MMSQLException</code> if a connection does not exist.
+	 * 
+	 * @throws Exception
+	 */
+	@Test(expected=MMSQLException.class) public void testUpdateException() throws Exception {
+		MMPreparedStatement statement = getMMPreparedStatement("delete from table"); //$NON-NLS-1$
+		statement.execute();
+	}
+	
+	/**
+	 * Verify that the <code>executeBatch()</code> method of <code>
+	 * MMPreparedStatement</code> is resulting in the correct command, 
+	 * parameter values for each command of the batch, and the request type 
+	 * are being set in the request message that would normally be sent to the 
+	 * server.
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testBatchedUpdateExecution() throws Exception {
+		// Build up a fake connection instance for use with the prepared statement
+		MMConnection conn = Mockito.mock(MMConnection.class);
+		ClientSideDQP dqp = Mockito.mock(ClientSideDQP.class);
+		ServerConnection serverConn = Mockito.mock(ServerConnection.class);
+		LogonResult logonResult = Mockito.mock(LogonResult.class);
+		
+		// stub methods
+		Mockito.stub(conn.getServerConnection()).toReturn(serverConn);
+		Mockito.stub(serverConn.getLogonResult()).toReturn(logonResult);
+		Mockito.stub(logonResult.getTimeZone()).toReturn(TimeZone.getDefault());
+
+		// a dummy result message that is specific to this test case
+		ResultsFuture<ResultsMessage> results = new ResultsFuture<ResultsMessage>(); 
+		Mockito.stub(dqp.executeRequest(Matchers.anyLong(), (RequestMessage)Matchers.anyObject())).toReturn(results);
+		ResultsMessage rm = new ResultsMessage();
+		rm.setResults(new List<?>[] {Arrays.asList(0), Arrays.asList(0), Arrays.asList(0)});
+		rm.setUpdateResult(true);
+		results.getResultsReceiver().receiveResults(rm);
+		Mockito.stub(conn.getDQP()).toReturn(dqp);
+		
+		// some update SQL
+		String sqlCommand = "delete from table where col=?"; //$NON-NLS-1$
+		TestableMMPreparedStatement statement = (TestableMMPreparedStatement) getMMPreparedStatement(conn, sqlCommand);
+
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(3);
+		// Add some batches and their parameter values
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(1) } ) ) );
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(2) } ) ) );
+		statement.setInt(1, new Integer(2));
+		statement.addBatch();
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(3) } ) ) );
+		statement.setInt(1, new Integer(3));
+		statement.addBatch();
+		
+		// execute the batch and verify that it matches our dummy results 
+		// message set earlier
+		assertTrue(Arrays.equals(new int[] {0, 0, 0}, statement.executeBatch()));
+		
+		// Now verify the statement's RequestMessage is what we expect 
+		assertEquals("Command does not match", sqlCommand, statement.requestMessage.getCommandString()); //$NON-NLS-1$
+		assertEquals("Parameter values do not match", expectedParameterValues, statement.requestMessage.getParameterValues()); //$NON-NLS-1$
+		assertTrue("RequestMessage.isPreparedBatchUpdate should be true", statement.requestMessage.isPreparedBatchUpdate()); //$NON-NLS-1$
+		assertFalse("RequestMessage.isBatchedUpdate should be false", statement.requestMessage.isBatchedUpdate()); //$NON-NLS-1$
+		assertFalse("RequestMessage.isCallableStatement should be false", statement.requestMessage.isCallableStatement()); //$NON-NLS-1$
+		assertTrue("RequestMessage.isPreparedStatement should be true", statement.requestMessage.isPreparedStatement()); //$NON-NLS-1$
+	}
+	
+	/**
+	 * Verify that the <code>clearBatch()</code> method of 
+	 * <code>MMPreparedStatement</code> is clearing the list of batched 
+	 * commands.
+	 * <p>
+	 * This is done by first adding command parameter values to the batch and 
+	 * then invoking the <code>clearBatch()</code> method.
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testClearBatch() throws Exception {
+		MMPreparedStatement statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+		// Add some stuff
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		statement.setInt(1, new Integer(2));
+		statement.addBatch();
+		// Make sure something is really there
+		assertTrue("MMPreparedStatement.ParameterValuesList should not be empty", statement.getParameterValuesList().size() > 0); //$NON-NLS-1$
+		// Now clear it
+		statement.clearBatch();
+		assertTrue("MMPreparedStatement.ParameterValuesList should be empty", statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+	}
+
+	/**
+	 * Adds additional batches of command parameter values to a prepared 
+	 * statement after a previous list has been cleared.
+	 * <p>
+	 * This is done by first adding command parameter values to the batch and 
+	 * then invoking the <code>clearBatch()</code> method.  Then a different 
+	 * set of command parameter values are added to the existing batch command.
+	 * <p>
+	 * The expected result is the command parameter list for the batches will 
+	 * only reflect what was added after <code>clearBatch()</code> was invoked.  
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testClearBatchAddBatch() throws Exception {
+		MMPreparedStatement statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+		
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		statement.setInt(1, new Integer(2));
+		statement.addBatch();
+		// Make sure something is really there
+		assertTrue("MMPreparedStatement.ParameterValuesList should not be empty", statement.getParameterValuesList().size() > 0); //$NON-NLS-1$
+		// Now clear it
+		statement.clearBatch();
+		// Make sure it is empty now
+		assertTrue("MMPreparedStatement.ParameterValuesList should be empty", statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(1);
+		
+		// Now add something for validation 
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(5) } ) ) );
+		statement.setInt(1, new Integer(5));
+		statement.addBatch();
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+	}
+
+	/**
+	 * Test the <code>addBatch()</code> method of <code>MMPreparedStatement</code> 
+	 * to verify that the command parameter values of the batch are added to the 
+	 * command parameter values list.
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testAddBatch() throws Exception {
+		MMPreparedStatement statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(1);
+		
+		// First we add a single batch 
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(1) } ) ) );
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+
+		// Now add some more batches just for sanity sake
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(3) } ) ) );
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(5) } ) ) );
+		statement.setInt(1, new Integer(3));
+		statement.addBatch();
+		statement.setInt(1, new Integer(5));
+		statement.addBatch();
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+	}
+
+	/**
+	 * Test the <code>addBatch()</code> method of <code>MMPreparedStatement</code> 
+	 * using a batch with an empty parameter value list.  The test will verify 
+	 * no failures occur when there are no command parameter values defined 
+	 * when the <code>addBatch()</code> method is invoked.
+	 * <p>
+	 * It is valid to add an empty parameter value list to a batch list.
+	 * <p>
+	 * For example:
+	 * <p>
+	 * <code>PreparedStatement stmt = conn.prepareStatement(sql);<br \>
+	 *  stmt.addBatch();<br \>
+	 *  stmt.addBatch();<br \>
+	 *  stmt.executeBatch();</code>
+	 *   
+	 * @throws Exception
+	 */
+	@Test public void testAddBatchNoParameterValues() throws Exception {
+		MMPreparedStatement statement = getMMPreparedStatement("delete from table where col=?"); //$NON-NLS-1$
+		
+		// This will hold our expected values list
+		ArrayList<ArrayList<Object>> expectedParameterValues = new ArrayList<ArrayList<Object>>(1);
+		
+		// First batch has an empty parameter value list
+		expectedParameterValues.add( new ArrayList<Object>(Collections.emptyList()) );
+
+		// No values have been set  so we are adding a batch with an empty 
+		// parameter value list
+		statement.addBatch();
+
+		// Second batch contains a parameter value list
+		expectedParameterValues.add( new ArrayList<Object>( Arrays.asList( new Object[] { new Integer(1) } ) ) );
+
+		// We now are adding a batch that does have parameter values
+		statement.setInt(1, new Integer(1));
+		statement.addBatch();
+
+		// Check to see if our statement contains our expected parameter value list
+		assertEquals("MMPreparedStatement.ParameterValuesList does not match", expectedParameterValues, statement.getParameterValuesList()); //$NON-NLS-1$
+	}
+
+	/**
+	 * A helper method to get an <code>MMPreparedStatement</code> that can be 
+	 * used for simple test cases.
+	 * <p>
+	 * The returned value is an instance of <code>TestableMMPreparedStatement</code>
+	 * <p>
+	 * This method invokes <code>getMMPreparedStatement(final MMConnection conn, 
+	 * final String sql)</code> with a fake connection object constructed by 
+	 * <code>Mockito</code>.
+	 *   
+	 * @param sql the query for the prepared statement
+	 * @return an instance of TestableMMPreparedStatement
+	 * @throws SQLException
+	 */
+	protected MMPreparedStatement getMMPreparedStatement(final String sql) throws SQLException {
+		MMConnection conn = Mockito.mock(MMConnection.class);
+		ServerConnection serverConn = Mockito.mock(ServerConnection.class);
+		LogonResult logonResult = Mockito.mock(LogonResult.class);
+		
+		Mockito.stub(conn.getServerConnection()).toReturn(serverConn);
+		Mockito.stub(serverConn.getLogonResult()).toReturn(logonResult);
+		Mockito.stub(logonResult.getTimeZone()).toReturn(TimeZone.getDefault());
+
+		return getMMPreparedStatement(conn, sql);
+	}
+	
+	/**
+	 * A helper method to get an <code>MMPreparedStatement</code> that can be 
+	 * used for simple test cases.
+	 * <p>
+	 * The returned value is an instance of <code>TestableMMPreparedStatement</code>
+	 * <p>
+	 * <code>conn</code> should be a valid instance of <code>MMConnection</code> 
+	 * or this method will fail.
+	 * 
+	 * @param conn an instance of <code>MMConnection</code>
+	 * @param sql the query for the prepared statement
+	 * @return an instance of TestableMMPreparedStatement
+	 * @throws SQLException
+	 */
+	protected MMPreparedStatement getMMPreparedStatement(final MMConnection conn, final String sql) throws SQLException {
+		TestableMMPreparedStatement statement = new TestableMMPreparedStatement(conn, sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+		
+		// Make sure everything is empty on start
+		assertTrue("MMPreparedStatement.ParameterValuesList should be empty", statement.getParameterValuesList().size() == 0); //$NON-NLS-1$
+		assertTrue("MMPreparedStatement.ParameterValues should be empty", statement.getParameterValues().size() == 0); //$NON-NLS-1$
+
+		return statement;
+	}
+	
+	/**
+	 * Represents an extension to <code>MMPreparedStatement</code> that 
+	 * gives access to the <code>RequestMessage</code> that is passed 
+	 * around inside <code>MMPreparedStatement</code>. 
+	 * <p>
+	 * This extension simply adds a field named <code>requestMessage</code> 
+	 * which is <code>public</code>.  This field gets set when the <code>protected</code>
+	 * method <code>createRequestMessage()</code> is called.
+	 * <p>
+	 * This extension also overrides <code>RequestMessage createRequestMessage(String[] commands,
+	 *			boolean isBatchedCommand, Boolean requiresResultSet)</code> so that 
+	 * reference to the created <code>RequestMessage</code> can be retained in 
+	 * the field <code>requestMessage</code>. 
+	 */
+	class TestableMMPreparedStatement extends MMPreparedStatement {
+		/**
+		 * Contains a reference to the <code>RequestMessage</code> created by 
+		 * a call to <code>createRequestMessage(String[] commands, 
+		 * boolean isBatchedCommand, Boolean requiresResultSet)</code>.  This
+		 * will allow easy access to the prepared statement's request message 
+		 * generated by a call to one of the statement's execute methods.
+		 */
+		public RequestMessage requestMessage;
+		@Override
+		protected RequestMessage createRequestMessage(String[] commands,
+				boolean isBatchedCommand, Boolean requiresResultSet) {
+			this.requestMessage = super
+					.createRequestMessage(commands, isBatchedCommand, requiresResultSet);
+			return this.requestMessage;
+		}
+
+		public TestableMMPreparedStatement(MMConnection connection,
+				String sql, int resultSetType, int resultSetConcurrency)
+				throws SQLException {
+			super(connection, sql, resultSetType, resultSetConcurrency);
+		}
+		
+	}
+
+}


Property changes on: trunk/client-jdbc/src/test/java/com/metamatrix/jdbc/TestMMPreparedStatement.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain




More information about the teiid-commits mailing list