1 package org.springframework.batch.item.database;
2
3 import static org.easymock.EasyMock.createMock;
4 import static org.easymock.EasyMock.createNiceMock;
5 import static org.easymock.EasyMock.expect;
6 import static org.easymock.EasyMock.replay;
7 import static org.easymock.EasyMock.verify;
8
9 import java.sql.CallableStatement;
10 import java.sql.Connection;
11 import java.sql.DatabaseMetaData;
12 import java.sql.PreparedStatement;
13 import java.sql.ResultSet;
14 import java.sql.SQLException;
15
16 import javax.sql.DataSource;
17
18 import org.hsqldb.Types;
19 import org.junit.Test;
20 import org.junit.internal.runners.JUnit4ClassRunner;
21 import org.junit.runner.RunWith;
22 import org.springframework.batch.item.ExecutionContext;
23 import org.springframework.jdbc.core.PreparedStatementSetter;
24 import org.springframework.jdbc.core.SqlParameter;
25 import org.springframework.jdbc.datasource.DataSourceTransactionManager;
26 import org.springframework.transaction.PlatformTransactionManager;
27 import org.springframework.transaction.TransactionStatus;
28 import org.springframework.transaction.support.TransactionCallback;
29 import org.springframework.transaction.support.TransactionTemplate;
30
31 @RunWith(JUnit4ClassRunner.class)
32 public class StoredprocedureItemReaderConfigTests {
33
34
35
36
37 @Test
38 public void testUsesCurrentTransaction() throws Exception {
39 DataSource ds = createMock(DataSource.class);
40 DatabaseMetaData dmd = createNiceMock(DatabaseMetaData.class);
41 expect(dmd.getDatabaseProductName()).andReturn("Oracle").times(2);
42 Connection con = createMock(Connection.class);
43 expect(con.getMetaData()).andReturn(dmd);
44 expect(con.getMetaData()).andReturn(dmd);
45 expect(con.getAutoCommit()).andReturn(false);
46 CallableStatement cs = createNiceMock(CallableStatement.class);
47 expect(con.prepareCall("{call foo_bar()}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY,
48 ResultSet.HOLD_CURSORS_OVER_COMMIT)).andReturn(cs);
49 expect(ds.getConnection()).andReturn(con);
50 expect(ds.getConnection()).andReturn(con);
51 con.commit();
52 replay(con,dmd, ds, cs);
53 PlatformTransactionManager tm = new DataSourceTransactionManager(ds);
54 TransactionTemplate tt = new TransactionTemplate(tm);
55 final StoredProcedureItemReader<String> reader = new StoredProcedureItemReader<String>();
56 reader.setDataSource(new ExtendedConnectionDataSourceProxy(ds));
57 reader.setUseSharedExtendedConnection(true);
58 reader.setProcedureName("foo_bar");
59 final ExecutionContext ec = new ExecutionContext();
60 tt.execute(
61 new TransactionCallback() {
62 public Object doInTransaction(TransactionStatus status) {
63 reader.open(ec);
64 reader.close();
65 return null;
66 }
67 });
68 verify(ds);
69 }
70
71
72
73
74 @Test
75 public void testUsesItsOwnTransaction() throws Exception {
76
77 DataSource ds = createMock(DataSource.class);
78 DatabaseMetaData dmd = createNiceMock(DatabaseMetaData.class);
79 expect(dmd.getDatabaseProductName()).andReturn("Oracle").times(2);
80 Connection con = createMock(Connection.class);
81 expect(con.getMetaData()).andReturn(dmd);
82 expect(con.getMetaData()).andReturn(dmd);
83 expect(con.getAutoCommit()).andReturn(false);
84 CallableStatement cs = createNiceMock(CallableStatement.class);
85 expect(con.prepareCall("{call foo_bar()}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)).andReturn(cs);
86 expect(ds.getConnection()).andReturn(con);
87 expect(ds.getConnection()).andReturn(con);
88 con.commit();
89 replay(con,dmd, ds, cs);
90 PlatformTransactionManager tm = new DataSourceTransactionManager(ds);
91 TransactionTemplate tt = new TransactionTemplate(tm);
92 final StoredProcedureItemReader<String> reader = new StoredProcedureItemReader<String>();
93 reader.setDataSource(ds);
94 reader.setProcedureName("foo_bar");
95 final ExecutionContext ec = new ExecutionContext();
96 tt.execute(
97 new TransactionCallback() {
98 public Object doInTransaction(TransactionStatus status) {
99 reader.open(ec);
100 reader.close();
101 return null;
102 }
103 });
104 verify(ds);
105 }
106
107
108
109
110 @Test
111 public void testHandlesRefCursorPosition() throws Exception {
112
113 DataSource ds = createMock(DataSource.class);
114 DatabaseMetaData dmd = createNiceMock(DatabaseMetaData.class);
115 expect(dmd.getDatabaseProductName()).andReturn("Oracle").times(2);
116 Connection con = createMock(Connection.class);
117 expect(con.getMetaData()).andReturn(dmd);
118 expect(con.getMetaData()).andReturn(dmd);
119 expect(con.getAutoCommit()).andReturn(false);
120 CallableStatement cs = createNiceMock(CallableStatement.class);
121 expect(con.prepareCall("{call foo_bar(?, ?)}", ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)).andReturn(cs);
122 expect(ds.getConnection()).andReturn(con);
123 expect(ds.getConnection()).andReturn(con);
124 con.commit();
125 replay(con,dmd, ds, cs);
126 PlatformTransactionManager tm = new DataSourceTransactionManager(ds);
127 TransactionTemplate tt = new TransactionTemplate(tm);
128 final StoredProcedureItemReader<String> reader = new StoredProcedureItemReader<String>();
129 reader.setDataSource(ds);
130 reader.setProcedureName("foo_bar");
131 reader.setParameters(new SqlParameter[] {
132 new SqlParameter("foo", Types.VARCHAR),
133 new SqlParameter("bar", Types.OTHER)});
134 reader.setPreparedStatementSetter(
135 new PreparedStatementSetter() {
136 public void setValues(PreparedStatement ps)
137 throws SQLException {
138 }
139 });
140 reader.setRefCursorPosition(3);
141 final ExecutionContext ec = new ExecutionContext();
142 tt.execute(
143 new TransactionCallback() {
144 public Object doInTransaction(TransactionStatus status) {
145 reader.open(ec);
146 reader.close();
147 return null;
148 }
149 });
150 verify(ds);
151 }
152 }