1 | |
package org.apache.ojb.broker.platforms; |
2 | |
|
3 | |
|
4 | |
|
5 | |
|
6 | |
|
7 | |
|
8 | |
|
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | |
|
16 | |
|
17 | |
|
18 | |
import java.io.ByteArrayInputStream; |
19 | |
import java.lang.reflect.Method; |
20 | |
import java.sql.Connection; |
21 | |
import java.sql.PreparedStatement; |
22 | |
import java.sql.SQLException; |
23 | |
import java.sql.Types; |
24 | |
import java.util.Collections; |
25 | |
import java.util.Map; |
26 | |
import java.util.WeakHashMap; |
27 | |
|
28 | |
import org.apache.ojb.broker.metadata.JdbcType; |
29 | |
import org.apache.ojb.broker.util.ClassHelper; |
30 | |
import org.apache.ojb.broker.metadata.JdbcTypesHelper; |
31 | |
|
32 | |
|
33 | |
|
34 | |
|
35 | |
|
36 | |
|
37 | |
|
38 | |
|
39 | |
|
40 | |
|
41 | |
|
42 | |
|
43 | |
|
44 | |
|
45 | |
|
46 | |
|
47 | |
|
48 | |
|
49 | |
|
50 | |
|
51 | |
|
52 | |
|
53 | |
|
54 | |
|
55 | |
|
56 | |
|
57 | |
|
58 | |
|
59 | |
|
60 | |
|
61 | |
|
62 | |
|
63 | |
|
64 | |
public class PlatformWLOracle9iImpl extends PlatformOracleImpl |
65 | |
{ |
66 | |
protected static final int ROW_PREFETCH_SIZE = 100; |
67 | |
|
68 | |
|
69 | |
|
70 | |
protected static final int STATEMENTS_PER_BATCH = 20; |
71 | |
protected static Map m_batchStatementsInProgress = Collections.synchronizedMap(new WeakHashMap(STATEMENTS_PER_BATCH)); |
72 | |
|
73 | |
protected static final Class[] PARAM_TYPE_INTEGER = {Integer.TYPE}; |
74 | |
protected static final Class[] PARAM_TYPE_BOOLEAN = {Boolean.TYPE}; |
75 | |
protected static final Class[] PARAM_TYPE_STRING = {String.class}; |
76 | |
|
77 | |
protected static final Object[] PARAM_ROW_PREFETCH_SIZE = new Object[]{new Integer(ROW_PREFETCH_SIZE)}; |
78 | |
protected static final Object[] PARAM_STATEMENT_BATCH_SIZE = new Object[]{new Integer(STATEMENTS_PER_BATCH)}; |
79 | |
protected static final Object[] PARAM_BOOLEAN_TRUE = new Object[]{Boolean.TRUE}; |
80 | |
|
81 | |
protected static final JdbcType BASE_CLOB = JdbcTypesHelper.getJdbcTypeByName("clob"); |
82 | |
protected static final JdbcType BASE_BLOB = JdbcTypesHelper.getJdbcTypeByName("blob"); |
83 | |
|
84 | |
|
85 | |
|
86 | |
|
87 | |
|
88 | |
|
89 | |
|
90 | |
|
91 | |
|
92 | |
|
93 | |
|
94 | |
public void afterStatementCreate(java.sql.Statement stmt) throws PlatformException |
95 | |
{ |
96 | |
super.afterStatementCreate(stmt); |
97 | |
|
98 | |
|
99 | |
final Method methodSetRowPrefetch; |
100 | |
methodSetRowPrefetch = ClassHelper.getMethod(stmt, "setRowPrefetch", PARAM_TYPE_INTEGER); |
101 | |
|
102 | |
final boolean rowPrefetchingSupported = methodSetRowPrefetch != null; |
103 | |
if (rowPrefetchingSupported) |
104 | |
{ |
105 | |
try |
106 | |
{ |
107 | |
|
108 | |
methodSetRowPrefetch.invoke(stmt, PARAM_ROW_PREFETCH_SIZE); |
109 | |
} |
110 | |
catch (Exception e) |
111 | |
{ |
112 | |
throw new PlatformException(e.getLocalizedMessage(), e); |
113 | |
} |
114 | |
} |
115 | |
} |
116 | |
|
117 | |
|
118 | |
|
119 | |
|
120 | |
|
121 | |
|
122 | |
|
123 | |
|
124 | |
public void beforeBatch(PreparedStatement stmt) throws PlatformException |
125 | |
{ |
126 | |
|
127 | |
final Method methodSetExecuteBatch; |
128 | |
final Method methodSendBatch; |
129 | |
methodSetExecuteBatch = ClassHelper.getMethod(stmt, "setExecuteBatch", PARAM_TYPE_INTEGER); |
130 | |
methodSendBatch = ClassHelper.getMethod(stmt, "sendBatch", null); |
131 | |
|
132 | |
final boolean statementBatchingSupported = methodSetExecuteBatch != null && methodSendBatch != null; |
133 | |
if (statementBatchingSupported) |
134 | |
{ |
135 | |
try |
136 | |
{ |
137 | |
|
138 | |
methodSetExecuteBatch.invoke(stmt, PARAM_STATEMENT_BATCH_SIZE); |
139 | |
m_batchStatementsInProgress.put(stmt, methodSendBatch); |
140 | |
} |
141 | |
catch (Exception e) |
142 | |
{ |
143 | |
throw new PlatformException(e.getLocalizedMessage(), e); |
144 | |
} |
145 | |
} |
146 | |
else |
147 | |
{ |
148 | |
super.beforeBatch(stmt); |
149 | |
} |
150 | |
} |
151 | |
|
152 | |
|
153 | |
|
154 | |
|
155 | |
|
156 | |
|
157 | |
|
158 | |
public void addBatch(PreparedStatement stmt) throws PlatformException |
159 | |
{ |
160 | |
|
161 | |
final boolean statementBatchingSupported = m_batchStatementsInProgress.containsKey(stmt); |
162 | |
if (statementBatchingSupported) |
163 | |
{ |
164 | |
try |
165 | |
{ |
166 | |
stmt.executeUpdate(); |
167 | |
} |
168 | |
catch (SQLException e) |
169 | |
{ |
170 | |
throw new PlatformException(e.getLocalizedMessage(), e); |
171 | |
} |
172 | |
} |
173 | |
else |
174 | |
{ |
175 | |
super.addBatch(stmt); |
176 | |
} |
177 | |
} |
178 | |
|
179 | |
|
180 | |
|
181 | |
|
182 | |
|
183 | |
|
184 | |
|
185 | |
|
186 | |
|
187 | |
|
188 | |
|
189 | |
public int[] executeBatch(PreparedStatement stmt) throws PlatformException |
190 | |
{ |
191 | |
|
192 | |
final Method methodSendBatch = (Method) m_batchStatementsInProgress.remove(stmt); |
193 | |
final boolean statementBatchingSupported = methodSendBatch != null; |
194 | |
|
195 | |
int[] retval = null; |
196 | |
if (statementBatchingSupported) |
197 | |
{ |
198 | |
try |
199 | |
{ |
200 | |
|
201 | |
methodSendBatch.invoke(stmt, null); |
202 | |
} |
203 | |
catch (Exception e) |
204 | |
{ |
205 | |
throw new PlatformException(e.getLocalizedMessage(), e); |
206 | |
} |
207 | |
} |
208 | |
else |
209 | |
{ |
210 | |
retval = super.executeBatch(stmt); |
211 | |
} |
212 | |
return retval; |
213 | |
} |
214 | |
|
215 | |
|
216 | |
public void setObjectForStatement(PreparedStatement ps, int index, Object value, int sqlType) throws SQLException |
217 | |
{ |
218 | |
boolean blobHandlingSupported = false; |
219 | |
boolean clobHandlingSupported = false; |
220 | |
Method methodSetBlob = null; |
221 | |
Method methodSetClob = null; |
222 | |
Method methodGetVendorConnection = null; |
223 | |
|
224 | |
|
225 | |
if (sqlType == Types.CLOB) |
226 | |
{ |
227 | |
try |
228 | |
{ |
229 | |
Class clobClass = ClassHelper.getClass("oracle.sql.CLOB", false); |
230 | |
methodSetClob = ClassHelper.getMethod(ps, "setCLOB", new Class[]{Integer.TYPE, clobClass}); |
231 | |
methodGetVendorConnection = ClassHelper.getMethod(ps.getConnection(), "getVendorConnection", |
232 | |
new Class[]{}); |
233 | |
clobHandlingSupported = methodSetClob != null && methodGetVendorConnection != null; |
234 | |
} |
235 | |
catch (Exception ignore) |
236 | |
{ |
237 | |
|
238 | |
} |
239 | |
} |
240 | |
else if (sqlType == Types.BLOB) |
241 | |
{ |
242 | |
try |
243 | |
{ |
244 | |
Class blobClass = ClassHelper.getClass("oracle.sql.BLOB", false); |
245 | |
methodSetBlob = ClassHelper.getMethod(ps, "setBLOB", new Class[]{Integer.TYPE, blobClass}); |
246 | |
methodGetVendorConnection = ClassHelper.getMethod(ps.getConnection(), "getVendorConnection", |
247 | |
new Class[]{}); |
248 | |
blobHandlingSupported = methodSetBlob != null && methodGetVendorConnection != null; |
249 | |
} |
250 | |
catch (Exception ignore) |
251 | |
{ |
252 | |
|
253 | |
} |
254 | |
} |
255 | |
|
256 | |
|
257 | |
if (((sqlType == Types.VARBINARY) || (sqlType == Types.LONGVARBINARY)) && (value instanceof byte[])) |
258 | |
{ |
259 | |
byte buf[] = (byte[]) value; |
260 | |
ByteArrayInputStream inputStream = new ByteArrayInputStream(buf); |
261 | |
super.changePreparedStatementResultSetType(ps); |
262 | |
ps.setBinaryStream(index, inputStream, buf.length); |
263 | |
} |
264 | |
else if (value instanceof Double) |
265 | |
{ |
266 | |
|
267 | |
ps.setDouble(index, ((Double) value).doubleValue()); |
268 | |
} |
269 | |
else if (sqlType == Types.BIGINT && value instanceof Integer) |
270 | |
{ |
271 | |
|
272 | |
ps.setLong(index, ((Integer) value).intValue()); |
273 | |
} |
274 | |
else if (sqlType == Types.INTEGER && value instanceof Long) |
275 | |
{ |
276 | |
ps.setLong(index, ((Long) value).longValue()); |
277 | |
} |
278 | |
else if (sqlType == Types.CLOB && clobHandlingSupported && value instanceof String) |
279 | |
{ |
280 | |
|
281 | |
try |
282 | |
{ |
283 | |
Connection vendorConnection = (Connection) methodGetVendorConnection.invoke(ps.getConnection(), |
284 | |
new Object[]{}); |
285 | |
Object clob = Oracle9iLobHandler.createCLOBFromString(vendorConnection, (String) value); |
286 | |
methodSetClob.invoke(ps, new Object[]{new Integer(index), clob}); |
287 | |
} |
288 | |
catch (Exception e) |
289 | |
{ |
290 | |
throw new SQLException(e.getLocalizedMessage()); |
291 | |
} |
292 | |
} |
293 | |
else if (sqlType == Types.BLOB && blobHandlingSupported && value instanceof byte[]) |
294 | |
{ |
295 | |
|
296 | |
try |
297 | |
{ |
298 | |
Connection vendorConnection = (Connection) methodGetVendorConnection.invoke(ps.getConnection(), |
299 | |
new Object[]{}); |
300 | |
Object blob = Oracle9iLobHandler.createBLOBFromByteArray(vendorConnection, (byte[]) value); |
301 | |
methodSetBlob.invoke(ps, new Object[]{new Integer(index), blob}); |
302 | |
} |
303 | |
catch (Exception e) |
304 | |
{ |
305 | |
throw new SQLException(e.getLocalizedMessage()); |
306 | |
} |
307 | |
} |
308 | |
else |
309 | |
{ |
310 | |
|
311 | |
super.setObjectForStatement(ps, index, value, sqlType); |
312 | |
} |
313 | |
} |
314 | |
|
315 | |
} |