1 /*
2  * Copyright 2002-2008 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  */
16 
17 package org.springframework.jdbc.object;
18 
19 import java.sql.DatabaseMetaData;
20 import java.sql.PreparedStatement;
21 import java.sql.Types;
22 
23 import org.easymock.MockControl;
24 import org.apache.commons.logging.LogFactory;
25 
26 import org.springframework.jdbc.AbstractJdbcTests;
27 import org.springframework.jdbc.core.SqlParameter;
28 import org.springframework.jdbc.core.JdbcTemplate;
29 
30 /**
31  * @author Juergen Hoeller
32  * @since 22.02.2005
33  */
34 public class BatchSqlUpdateTests extends AbstractJdbcTests {
35 
36 	private final boolean debugEnabled = LogFactory.getLog(JdbcTemplate.class).isDebugEnabled();
37 
38 
testBatchUpdateWithExplicitFlush()39 	public void testBatchUpdateWithExplicitFlush() throws Exception {
40 		doTestBatchUpdate(false);
41 	}
42 
testBatchUpdateWithFlushThroughBatchSize()43 	public void testBatchUpdateWithFlushThroughBatchSize() throws Exception {
44 		doTestBatchUpdate(true);
45 	}
46 
doTestBatchUpdate(boolean flushThroughBatchSize)47 	private void doTestBatchUpdate(boolean flushThroughBatchSize) throws Exception {
48 		final String sql = "UPDATE NOSUCHTABLE SET DATE_DISPATCHED = SYSDATE WHERE ID = ?";
49 		final int[] ids = new int[] { 100, 200 };
50 		final int[] rowsAffected = new int[] { 1, 2 };
51 
52 		MockControl ctrlPreparedStatement = MockControl.createControl(PreparedStatement.class);
53 		PreparedStatement mockPreparedStatement = (PreparedStatement) ctrlPreparedStatement.getMock();
54 		mockPreparedStatement.getConnection();
55 		ctrlPreparedStatement.setReturnValue(mockConnection);
56 		mockPreparedStatement.setObject(1, new Integer(ids[0]), Types.INTEGER);
57 		ctrlPreparedStatement.setVoidCallable();
58 		mockPreparedStatement.addBatch();
59 		ctrlPreparedStatement.setVoidCallable();
60 		mockPreparedStatement.setObject(1, new Integer(ids[1]), Types.INTEGER);
61 		ctrlPreparedStatement.setVoidCallable();
62 		mockPreparedStatement.addBatch();
63 		ctrlPreparedStatement.setVoidCallable();
64 		mockPreparedStatement.executeBatch();
65 		ctrlPreparedStatement.setReturnValue(rowsAffected);
66 		if (debugEnabled) {
67 			mockPreparedStatement.getWarnings();
68 			ctrlPreparedStatement.setReturnValue(null);
69 		}
70 		mockPreparedStatement.close();
71 		ctrlPreparedStatement.setVoidCallable();
72 
73 		MockControl ctrlDatabaseMetaData = MockControl.createControl(DatabaseMetaData.class);
74 		DatabaseMetaData mockDatabaseMetaData = (DatabaseMetaData) ctrlDatabaseMetaData.getMock();
75 		mockDatabaseMetaData.supportsBatchUpdates();
76 		ctrlDatabaseMetaData.setReturnValue(true);
77 
78 		mockConnection.prepareStatement(sql);
79 		ctrlConnection.setReturnValue(mockPreparedStatement);
80 		mockConnection.getMetaData();
81 		ctrlConnection.setReturnValue(mockDatabaseMetaData, 1);
82 
83 		ctrlPreparedStatement.replay();
84 		ctrlDatabaseMetaData.replay();
85 		replay();
86 
87 		BatchSqlUpdate update = new BatchSqlUpdate(mockDataSource, sql);
88 		update.declareParameter(new SqlParameter(Types.INTEGER));
89 		if (flushThroughBatchSize) {
90 			update.setBatchSize(2);
91 		}
92 
93 		update.update(ids[0]);
94 		update.update(ids[1]);
95 
96 		if (flushThroughBatchSize) {
97 			assertEquals(0, update.getQueueCount());
98 			assertEquals(2, update.getRowsAffected().length);
99 		}
100 		else {
101 			assertEquals(2, update.getQueueCount());
102 			assertEquals(0, update.getRowsAffected().length);
103 		}
104 
105 		int[] actualRowsAffected = update.flush();
106 		assertEquals(0, update.getQueueCount());
107 
108 		if (flushThroughBatchSize) {
109 			assertTrue("flush did not execute updates", actualRowsAffected.length == 0);
110 		}
111 		else {
112 			assertTrue("executed 2 updates", actualRowsAffected.length == 2);
113 			assertEquals(rowsAffected[0], actualRowsAffected[0]);
114 			assertEquals(rowsAffected[1], actualRowsAffected[1]);
115 		}
116 
117 		actualRowsAffected = update.getRowsAffected();
118 		assertTrue("executed 2 updates", actualRowsAffected.length == 2);
119 		assertEquals(rowsAffected[0], actualRowsAffected[0]);
120 		assertEquals(rowsAffected[1], actualRowsAffected[1]);
121 
122 		update.reset();
123 		assertEquals(0, update.getRowsAffected().length);
124 
125 		ctrlPreparedStatement.verify();
126 		ctrlDatabaseMetaData.verify();
127 	}
128 
129 }
130