1 | /* |
2 | Copyright (C) 2002-2006 MySQL AB |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of version 2 of the GNU General Public License as |
6 | published by the Free Software Foundation. |
7 | |
8 | There are special exceptions to the terms and conditions of the GPL |
9 | as it is applied to this software. View the full text of the |
10 | exception in file EXCEPTIONS-CONNECTOR-J in the directory of this |
11 | software distribution. |
12 | |
13 | This program is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with this program; if not, write to the Free Software |
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | |
22 | |
23 | |
24 | */ |
25 | package com.mysql.jdbc.jdbc2.optional; |
26 | |
27 | import java.sql.Connection; |
28 | import java.sql.SQLException; |
29 | import java.sql.Savepoint; |
30 | import java.sql.Statement; |
31 | |
32 | import com.mysql.jdbc.MysqlErrorNumbers; |
33 | import com.mysql.jdbc.SQLError; |
34 | |
35 | /** |
36 | * This class serves as a wrapper for the org.gjt.mm.mysql.jdbc2.Connection |
37 | * class. It is returned to the application server which may wrap it again and |
38 | * then return it to the application client in response to |
39 | * dataSource.getConnection(). |
40 | * |
41 | * <p> |
42 | * All method invocations are forwarded to org.gjt.mm.mysql.jdbc2.Connection |
43 | * unless the close method was previously called, in which case a sqlException |
44 | * is thrown. The close method performs a 'logical close' on the connection. |
45 | * </p> |
46 | * |
47 | * <p> |
48 | * All sqlExceptions thrown by the physical connection are intercepted and sent |
49 | * to connectionEvent listeners before being thrown to client. |
50 | * </p> |
51 | * |
52 | * @author Todd Wolff todd.wolff_at_prodigy.net |
53 | * |
54 | * @see org.gjt.mm.mysql.jdbc2.Connection |
55 | * @see org.gjt.mm.mysql.jdbc2.optional.MysqlPooledConnection |
56 | */ |
57 | public class ConnectionWrapper extends WrapperBase implements Connection { |
58 | private com.mysql.jdbc.Connection mc = null; |
59 | |
60 | private MysqlPooledConnection mpc = null; |
61 | |
62 | private String invalidHandleStr = "Logical handle no longer valid"; |
63 | |
64 | private boolean closed; |
65 | private boolean isForXa; |
66 | |
67 | /** |
68 | * Construct a new LogicalHandle and set instance variables |
69 | * |
70 | * @param mysqlPooledConnection |
71 | * reference to object that instantiated this object |
72 | * @param mysqlConnection |
73 | * physical connection to db |
74 | * |
75 | * @throws SQLException |
76 | * if an error occurs. |
77 | */ |
78 | public ConnectionWrapper(MysqlPooledConnection mysqlPooledConnection, |
79 | com.mysql.jdbc.Connection mysqlConnection, |
80 | boolean forXa) throws SQLException { |
81 | this.mpc = mysqlPooledConnection; |
82 | this.mc = mysqlConnection; |
83 | this.closed = false; |
84 | this.pooledConnection = this.mpc; |
85 | this.isForXa = forXa; |
86 | |
87 | if (this.isForXa) { |
88 | setInGlobalTx(false); |
89 | setAutoCommit(false); |
90 | } |
91 | } |
92 | |
93 | /** |
94 | * Passes call to method on physical connection instance. Notifies listeners |
95 | * of any caught exceptions before re-throwing to client. |
96 | * |
97 | * @see java.sql.Connection#setAutoCommit |
98 | */ |
99 | public void setAutoCommit(boolean autoCommit) throws SQLException { |
100 | checkClosed(); |
101 | |
102 | if (autoCommit && isInGlobalTx()) { |
103 | throw SQLError.createSQLException("Can't set autocommit to 'true' on an XAConnection", |
104 | SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, |
105 | MysqlErrorNumbers.ER_XA_RMERR); |
106 | } |
107 | |
108 | try { |
109 | this.mc.setAutoCommit(autoCommit); |
110 | } catch (SQLException sqlException) { |
111 | checkAndFireConnectionError(sqlException); |
112 | } |
113 | } |
114 | |
115 | /** |
116 | * Passes call to method on physical connection instance. Notifies listeners |
117 | * of any caught exceptions before re-throwing to client. |
118 | * |
119 | * @see java.sql.Connection#getAutoCommit() |
120 | */ |
121 | public boolean getAutoCommit() throws SQLException { |
122 | checkClosed(); |
123 | |
124 | try { |
125 | return this.mc.getAutoCommit(); |
126 | } catch (SQLException sqlException) { |
127 | checkAndFireConnectionError(sqlException); |
128 | } |
129 | |
130 | return false; // we don't reach this code, compiler can't tell |
131 | } |
132 | |
133 | /** |
134 | * Passes call to method on physical connection instance. Notifies listeners |
135 | * of any caught exceptions before re-throwing to client. |
136 | * |
137 | * @see java.sql.Connection#setCatalog() |
138 | */ |
139 | public void setCatalog(String catalog) throws SQLException { |
140 | checkClosed(); |
141 | |
142 | try { |
143 | this.mc.setCatalog(catalog); |
144 | } catch (SQLException sqlException) { |
145 | checkAndFireConnectionError(sqlException); |
146 | } |
147 | } |
148 | |
149 | /** |
150 | * Passes call to method on physical connection instance. Notifies listeners |
151 | * of any caught exceptions before re-throwing to client. |
152 | * |
153 | * @return the current catalog |
154 | * |
155 | * @throws SQLException |
156 | * if an error occurs |
157 | */ |
158 | public String getCatalog() throws SQLException { |
159 | checkClosed(); |
160 | |
161 | try { |
162 | return this.mc.getCatalog(); |
163 | } catch (SQLException sqlException) { |
164 | checkAndFireConnectionError(sqlException); |
165 | } |
166 | |
167 | return null; // we don't reach this code, compiler can't tell |
168 | } |
169 | |
170 | /** |
171 | * Passes call to method on physical connection instance. Notifies listeners |
172 | * of any caught exceptions before re-throwing to client. |
173 | * |
174 | * @see java.sql.Connection#isClosed() |
175 | */ |
176 | public boolean isClosed() throws SQLException { |
177 | return (this.closed || this.mc.isClosed()); |
178 | } |
179 | |
180 | public boolean isMasterConnection() throws SQLException { |
181 | return this.mc.isMasterConnection(); |
182 | } |
183 | |
184 | /** |
185 | * @see Connection#setHoldability(int) |
186 | */ |
187 | public void setHoldability(int arg0) throws SQLException { |
188 | checkClosed(); |
189 | |
190 | try { |
191 | this.mc.setHoldability(arg0); |
192 | } catch (SQLException sqlException) { |
193 | checkAndFireConnectionError(sqlException); |
194 | } |
195 | } |
196 | |
197 | /** |
198 | * @see Connection#getHoldability() |
199 | */ |
200 | public int getHoldability() throws SQLException { |
201 | checkClosed(); |
202 | |
203 | try { |
204 | return this.mc.getHoldability(); |
205 | } catch (SQLException sqlException) { |
206 | checkAndFireConnectionError(sqlException); |
207 | } |
208 | |
209 | return Statement.CLOSE_CURRENT_RESULT; // we don't reach this code, |
210 | // compiler can't tell |
211 | } |
212 | |
213 | /** |
214 | * Allows clients to determine how long this connection has been idle. |
215 | * |
216 | * @return how long the connection has been idle. |
217 | */ |
218 | public long getIdleFor() { |
219 | return this.mc.getIdleFor(); |
220 | } |
221 | |
222 | /** |
223 | * Passes call to method on physical connection instance. Notifies listeners |
224 | * of any caught exceptions before re-throwing to client. |
225 | * |
226 | * @return a metadata instance |
227 | * |
228 | * @throws SQLException |
229 | * if an error occurs |
230 | */ |
231 | public java.sql.DatabaseMetaData getMetaData() throws SQLException { |
232 | checkClosed(); |
233 | |
234 | try { |
235 | return this.mc.getMetaData(); |
236 | } catch (SQLException sqlException) { |
237 | checkAndFireConnectionError(sqlException); |
238 | } |
239 | |
240 | return null; // we don't reach this code, compiler can't tell |
241 | } |
242 | |
243 | /** |
244 | * Passes call to method on physical connection instance. Notifies listeners |
245 | * of any caught exceptions before re-throwing to client. |
246 | * |
247 | * @see java.sql.Connection#setReadOnly() |
248 | */ |
249 | public void setReadOnly(boolean readOnly) throws SQLException { |
250 | checkClosed(); |
251 | |
252 | try { |
253 | this.mc.setReadOnly(readOnly); |
254 | } catch (SQLException sqlException) { |
255 | checkAndFireConnectionError(sqlException); |
256 | } |
257 | } |
258 | |
259 | /** |
260 | * Passes call to method on physical connection instance. Notifies listeners |
261 | * of any caught exceptions before re-throwing to client. |
262 | * |
263 | * @see java.sql.Connection#isReadOnly() |
264 | */ |
265 | public boolean isReadOnly() throws SQLException { |
266 | checkClosed(); |
267 | |
268 | try { |
269 | return this.mc.isReadOnly(); |
270 | } catch (SQLException sqlException) { |
271 | checkAndFireConnectionError(sqlException); |
272 | } |
273 | |
274 | return false; // we don't reach this code, compiler can't tell |
275 | } |
276 | |
277 | /** |
278 | * @see Connection#setSavepoint() |
279 | */ |
280 | public java.sql.Savepoint setSavepoint() throws SQLException { |
281 | checkClosed(); |
282 | |
283 | if (isInGlobalTx()) { |
284 | throw SQLError.createSQLException("Can't set autocommit to 'true' on an XAConnection", |
285 | SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, |
286 | MysqlErrorNumbers.ER_XA_RMERR); |
287 | } |
288 | |
289 | try { |
290 | return this.mc.setSavepoint(); |
291 | } catch (SQLException sqlException) { |
292 | checkAndFireConnectionError(sqlException); |
293 | } |
294 | |
295 | return null; // we don't reach this code, compiler can't tell |
296 | } |
297 | |
298 | /** |
299 | * @see Connection#setSavepoint(String) |
300 | */ |
301 | public java.sql.Savepoint setSavepoint(String arg0) throws SQLException { |
302 | checkClosed(); |
303 | |
304 | if (isInGlobalTx()) { |
305 | throw SQLError.createSQLException("Can't set autocommit to 'true' on an XAConnection", |
306 | SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, |
307 | MysqlErrorNumbers.ER_XA_RMERR); |
308 | } |
309 | |
310 | try { |
311 | return this.mc.setSavepoint(arg0); |
312 | } catch (SQLException sqlException) { |
313 | checkAndFireConnectionError(sqlException); |
314 | } |
315 | |
316 | return null; // we don't reach this code, compiler can't tell |
317 | } |
318 | |
319 | /** |
320 | * Passes call to method on physical connection instance. Notifies listeners |
321 | * of any caught exceptions before re-throwing to client. |
322 | * |
323 | * @see java.sql.Connection#setTransactionIsolation() |
324 | */ |
325 | public void setTransactionIsolation(int level) throws SQLException { |
326 | checkClosed(); |
327 | |
328 | try { |
329 | this.mc.setTransactionIsolation(level); |
330 | } catch (SQLException sqlException) { |
331 | checkAndFireConnectionError(sqlException); |
332 | } |
333 | } |
334 | |
335 | /** |
336 | * Passes call to method on physical connection instance. Notifies listeners |
337 | * of any caught exceptions before re-throwing to client. |
338 | * |
339 | * @see java.sql.Connection#getTransactionIsolation() |
340 | */ |
341 | public int getTransactionIsolation() throws SQLException { |
342 | checkClosed(); |
343 | |
344 | try { |
345 | return this.mc.getTransactionIsolation(); |
346 | } catch (SQLException sqlException) { |
347 | checkAndFireConnectionError(sqlException); |
348 | } |
349 | |
350 | return TRANSACTION_REPEATABLE_READ; // we don't reach this code, |
351 | // compiler can't tell |
352 | } |
353 | |
354 | /** |
355 | * Passes call to method on physical connection instance. Notifies listeners |
356 | * of any caught exceptions before re-throwing to client. |
357 | * |
358 | * @see java.sql.Connection#setTypeMap() |
359 | */ |
360 | public void setTypeMap(java.util.Map map) throws SQLException { |
361 | checkClosed(); |
362 | |
363 | try { |
364 | this.mc.setTypeMap(map); |
365 | } catch (SQLException sqlException) { |
366 | checkAndFireConnectionError(sqlException); |
367 | } |
368 | } |
369 | |
370 | /** |
371 | * Passes call to method on physical connection instance. Notifies listeners |
372 | * of any caught exceptions before re-throwing to client. |
373 | * |
374 | * @see java.sql.Connection#getTypeMap() |
375 | */ |
376 | public java.util.Map getTypeMap() throws SQLException { |
377 | checkClosed(); |
378 | |
379 | try { |
380 | return this.mc.getTypeMap(); |
381 | } catch (SQLException sqlException) { |
382 | checkAndFireConnectionError(sqlException); |
383 | } |
384 | |
385 | return null; // we don't reach this code, compiler can't tell |
386 | } |
387 | |
388 | /** |
389 | * Passes call to method on physical connection instance. Notifies listeners |
390 | * of any caught exceptions before re-throwing to client. |
391 | * |
392 | * @see java.sql.Connection#getWarnings |
393 | */ |
394 | public java.sql.SQLWarning getWarnings() throws SQLException { |
395 | checkClosed(); |
396 | |
397 | try { |
398 | return this.mc.getWarnings(); |
399 | } catch (SQLException sqlException) { |
400 | checkAndFireConnectionError(sqlException); |
401 | } |
402 | |
403 | return null; // we don't reach this code, compiler can't tell |
404 | } |
405 | |
406 | /** |
407 | * Passes call to method on physical connection instance. Notifies listeners |
408 | * of any caught exceptions before re-throwing to client. |
409 | * |
410 | * @throws SQLException |
411 | * if an error occurs |
412 | */ |
413 | public void clearWarnings() throws SQLException { |
414 | checkClosed(); |
415 | |
416 | try { |
417 | this.mc.clearWarnings(); |
418 | } catch (SQLException sqlException) { |
419 | checkAndFireConnectionError(sqlException); |
420 | } |
421 | } |
422 | |
423 | /** |
424 | * The physical connection is not actually closed. the physical connection |
425 | * is closed when the application server calls |
426 | * mysqlPooledConnection.close(). this object is de-referenced by the pooled |
427 | * connection each time mysqlPooledConnection.getConnection() is called by |
428 | * app server. |
429 | * |
430 | * @throws SQLException |
431 | * if an error occurs |
432 | */ |
433 | public void close() throws SQLException { |
434 | close(true); |
435 | } |
436 | |
437 | /** |
438 | * Passes call to method on physical connection instance. Notifies listeners |
439 | * of any caught exceptions before re-throwing to client. |
440 | * |
441 | * @throws SQLException |
442 | * if an error occurs |
443 | */ |
444 | public void commit() throws SQLException { |
445 | checkClosed(); |
446 | |
447 | if (isInGlobalTx()) { |
448 | throw SQLError.createSQLException( |
449 | "Can't call commit() on an XAConnection associated with a global transaction", |
450 | SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, |
451 | MysqlErrorNumbers.ER_XA_RMERR); |
452 | } |
453 | |
454 | try { |
455 | this.mc.commit(); |
456 | } catch (SQLException sqlException) { |
457 | checkAndFireConnectionError(sqlException); |
458 | } |
459 | } |
460 | |
461 | /** |
462 | * Passes call to method on physical connection instance. Notifies listeners |
463 | * of any caught exceptions before re-throwing to client. |
464 | * |
465 | * @see java.sql.Connection#createStatement() |
466 | */ |
467 | public java.sql.Statement createStatement() throws SQLException { |
468 | checkClosed(); |
469 | |
470 | try { |
471 | return new StatementWrapper(this, this.mpc, this.mc |
472 | .createStatement()); |
473 | } catch (SQLException sqlException) { |
474 | checkAndFireConnectionError(sqlException); |
475 | } |
476 | |
477 | return null; // we don't reach this code, compiler can't tell |
478 | } |
479 | |
480 | /** |
481 | * Passes call to method on physical connection instance. Notifies listeners |
482 | * of any caught exceptions before re-throwing to client. |
483 | * |
484 | * @see java.sql.Connection#createStatement() |
485 | */ |
486 | public java.sql.Statement createStatement(int resultSetType, |
487 | int resultSetConcurrency) throws SQLException { |
488 | checkClosed(); |
489 | |
490 | try { |
491 | return new StatementWrapper(this, this.mpc, this.mc |
492 | .createStatement(resultSetType, resultSetConcurrency)); |
493 | } catch (SQLException sqlException) { |
494 | checkAndFireConnectionError(sqlException); |
495 | } |
496 | |
497 | return null; // we don't reach this code, compiler can't tell |
498 | } |
499 | |
500 | /** |
501 | * @see Connection#createStatement(int, int, int) |
502 | */ |
503 | public java.sql.Statement createStatement(int arg0, int arg1, int arg2) |
504 | throws SQLException { |
505 | checkClosed(); |
506 | |
507 | try { |
508 | return new StatementWrapper(this, this.mpc, this.mc |
509 | .createStatement(arg0, arg1, arg2)); |
510 | } catch (SQLException sqlException) { |
511 | checkAndFireConnectionError(sqlException); |
512 | } |
513 | |
514 | return null; // we don't reach this code, compiler can't tell |
515 | } |
516 | |
517 | /** |
518 | * Passes call to method on physical connection instance. Notifies listeners |
519 | * of any caught exceptions before re-throwing to client. |
520 | * |
521 | * @see java.sql.Connection#nativeSQL() |
522 | */ |
523 | public String nativeSQL(String sql) throws SQLException { |
524 | checkClosed(); |
525 | |
526 | try { |
527 | return this.mc.nativeSQL(sql); |
528 | } catch (SQLException sqlException) { |
529 | checkAndFireConnectionError(sqlException); |
530 | } |
531 | |
532 | return null; // we don't reach this code, compiler can't tell |
533 | } |
534 | |
535 | /** |
536 | * Passes call to method on physical connection instance. Notifies listeners |
537 | * of any caught exceptions before re-throwing to client. |
538 | * |
539 | * @see java.sql.Connection#prepareCall() |
540 | */ |
541 | public java.sql.CallableStatement prepareCall(String sql) |
542 | throws SQLException { |
543 | checkClosed(); |
544 | |
545 | try { |
546 | return new CallableStatementWrapper(this, this.mpc, this.mc |
547 | .prepareCall(sql)); |
548 | } catch (SQLException sqlException) { |
549 | checkAndFireConnectionError(sqlException); |
550 | } |
551 | |
552 | return null; // we don't reach this code, compiler can't tell |
553 | } |
554 | |
555 | /** |
556 | * Passes call to method on physical connection instance. Notifies listeners |
557 | * of any caught exceptions before re-throwing to client. |
558 | * |
559 | * @see java.sql.Connection#prepareCall() |
560 | */ |
561 | public java.sql.CallableStatement prepareCall(String sql, |
562 | int resultSetType, int resultSetConcurrency) throws SQLException { |
563 | checkClosed(); |
564 | |
565 | try { |
566 | return new CallableStatementWrapper(this, this.mpc, this.mc |
567 | .prepareCall(sql, resultSetType, resultSetConcurrency)); |
568 | } catch (SQLException sqlException) { |
569 | checkAndFireConnectionError(sqlException); |
570 | } |
571 | |
572 | return null; // we don't reach this code, compiler can't tell |
573 | } |
574 | |
575 | /** |
576 | * @see Connection#prepareCall(String, int, int, int) |
577 | */ |
578 | public java.sql.CallableStatement prepareCall(String arg0, int arg1, |
579 | int arg2, int arg3) throws SQLException { |
580 | checkClosed(); |
581 | |
582 | try { |
583 | return new CallableStatementWrapper(this, this.mpc, this.mc |
584 | .prepareCall(arg0, arg1, arg2, arg3)); |
585 | } catch (SQLException sqlException) { |
586 | checkAndFireConnectionError(sqlException); |
587 | } |
588 | |
589 | return null; // we don't reach this code, compiler can't tell |
590 | } |
591 | |
592 | public java.sql.PreparedStatement clientPrepare(String sql) throws SQLException |
593 | { |
594 | checkClosed(); |
595 | |
596 | try { |
597 | return new PreparedStatementWrapper(this, this.mpc, |
598 | this.mc.clientPrepareStatement(sql)); |
599 | } catch (SQLException sqlException) { |
600 | checkAndFireConnectionError(sqlException); |
601 | } |
602 | |
603 | return null; |
604 | } |
605 | |
606 | public java.sql.PreparedStatement clientPrepare(String sql, |
607 | int resultSetType, int resultSetConcurrency) throws SQLException |
608 | { |
609 | checkClosed(); |
610 | |
611 | try { |
612 | return new PreparedStatementWrapper(this, this.mpc, |
613 | this.mc.clientPrepareStatement(sql, |
614 | resultSetType, resultSetConcurrency)); |
615 | } catch (SQLException sqlException) { |
616 | checkAndFireConnectionError(sqlException); |
617 | } |
618 | |
619 | return null; |
620 | } |
621 | |
622 | /** |
623 | * Passes call to method on physical connection instance. Notifies listeners |
624 | * of any caught exceptions before re-throwing to client. |
625 | * |
626 | * @see java.sql.Connection#prepareStatement() |
627 | */ |
628 | public java.sql.PreparedStatement prepareStatement(String sql) |
629 | throws SQLException { |
630 | checkClosed(); |
631 | |
632 | try { |
633 | return new PreparedStatementWrapper(this, this.mpc, this.mc |
634 | .prepareStatement(sql)); |
635 | } catch (SQLException sqlException) { |
636 | checkAndFireConnectionError(sqlException); |
637 | } |
638 | |
639 | return null; // we don't reach this code, compiler can't tell |
640 | } |
641 | |
642 | /** |
643 | * Passes call to method on physical connection instance. Notifies listeners |
644 | * of any caught exceptions before re-throwing to client. |
645 | * |
646 | * @see java.sql.Connection#prepareStatement() |
647 | */ |
648 | public java.sql.PreparedStatement prepareStatement(String sql, |
649 | int resultSetType, int resultSetConcurrency) throws SQLException { |
650 | checkClosed(); |
651 | |
652 | try { |
653 | return new PreparedStatementWrapper(this, this.mpc, this.mc |
654 | .prepareStatement(sql, resultSetType, resultSetConcurrency)); |
655 | } catch (SQLException sqlException) { |
656 | checkAndFireConnectionError(sqlException); |
657 | } |
658 | |
659 | return null; // we don't reach this code, compiler can't tell |
660 | } |
661 | |
662 | /** |
663 | * @see Connection#prepareStatement(String, int, int, int) |
664 | */ |
665 | public java.sql.PreparedStatement prepareStatement(String arg0, int arg1, |
666 | int arg2, int arg3) throws SQLException { |
667 | checkClosed(); |
668 | |
669 | try { |
670 | return new PreparedStatementWrapper(this, this.mpc, this.mc |
671 | .prepareStatement(arg0, arg1, arg2, arg3)); |
672 | } catch (SQLException sqlException) { |
673 | checkAndFireConnectionError(sqlException); |
674 | } |
675 | |
676 | return null; // we don't reach this code, compiler can't tell |
677 | } |
678 | |
679 | /** |
680 | * @see Connection#prepareStatement(String, int) |
681 | */ |
682 | public java.sql.PreparedStatement prepareStatement(String arg0, int arg1) |
683 | throws SQLException { |
684 | checkClosed(); |
685 | |
686 | try { |
687 | return new PreparedStatementWrapper(this, this.mpc, this.mc |
688 | .prepareStatement(arg0, arg1)); |
689 | } catch (SQLException sqlException) { |
690 | checkAndFireConnectionError(sqlException); |
691 | } |
692 | |
693 | return null; // we don't reach this code, compiler can't tell |
694 | } |
695 | |
696 | /** |
697 | * @see Connection#prepareStatement(String, int[]) |
698 | */ |
699 | public java.sql.PreparedStatement prepareStatement(String arg0, int[] arg1) |
700 | throws SQLException { |
701 | checkClosed(); |
702 | |
703 | try { |
704 | return new PreparedStatementWrapper(this, this.mpc, this.mc |
705 | .prepareStatement(arg0, arg1)); |
706 | } catch (SQLException sqlException) { |
707 | checkAndFireConnectionError(sqlException); |
708 | } |
709 | |
710 | return null; // we don't reach this code, compiler can't tell |
711 | } |
712 | |
713 | /** |
714 | * @see Connection#prepareStatement(String, String[]) |
715 | */ |
716 | public java.sql.PreparedStatement prepareStatement(String arg0, |
717 | String[] arg1) throws SQLException { |
718 | checkClosed(); |
719 | |
720 | try { |
721 | return new PreparedStatementWrapper(this, this.mpc, this.mc |
722 | .prepareStatement(arg0, arg1)); |
723 | } catch (SQLException sqlException) { |
724 | checkAndFireConnectionError(sqlException); |
725 | } |
726 | |
727 | return null; // we don't reach this code, compiler can't tell |
728 | } |
729 | |
730 | /** |
731 | * @see Connection#releaseSavepoint(Savepoint) |
732 | */ |
733 | public void releaseSavepoint(Savepoint arg0) throws SQLException { |
734 | checkClosed(); |
735 | |
736 | try { |
737 | this.mc.releaseSavepoint(arg0); |
738 | } catch (SQLException sqlException) { |
739 | checkAndFireConnectionError(sqlException); |
740 | } |
741 | } |
742 | |
743 | /** |
744 | * Passes call to method on physical connection instance. Notifies listeners |
745 | * of any caught exceptions before re-throwing to client. |
746 | * |
747 | * @see java.sql.Connection#rollback() |
748 | */ |
749 | public void rollback() throws SQLException { |
750 | checkClosed(); |
751 | |
752 | |
753 | if (isInGlobalTx()) { |
754 | throw SQLError.createSQLException("Can't call rollback() on an XAConnection associated with a global transaction", |
755 | SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, |
756 | MysqlErrorNumbers.ER_XA_RMERR); |
757 | } |
758 | |
759 | try { |
760 | this.mc.rollback(); |
761 | } catch (SQLException sqlException) { |
762 | checkAndFireConnectionError(sqlException); |
763 | } |
764 | } |
765 | |
766 | /** |
767 | * @see Connection#rollback(Savepoint) |
768 | */ |
769 | public void rollback(Savepoint arg0) throws SQLException { |
770 | checkClosed(); |
771 | |
772 | if (isInGlobalTx()) { |
773 | throw SQLError.createSQLException("Can't call rollback() on an XAConnection associated with a global transaction", |
774 | SQLError.SQL_STATE_INVALID_TRANSACTION_TERMINATION, |
775 | MysqlErrorNumbers.ER_XA_RMERR); |
776 | } |
777 | |
778 | try { |
779 | this.mc.rollback(arg0); |
780 | } catch (SQLException sqlException) { |
781 | checkAndFireConnectionError(sqlException); |
782 | } |
783 | } |
784 | |
785 | public boolean isSameResource(Connection c) { |
786 | if (c instanceof ConnectionWrapper) { |
787 | return this.mc.isSameResource(((ConnectionWrapper)c).mc); |
788 | } else if (c instanceof com.mysql.jdbc.Connection) { |
789 | return this.mc.isSameResource((com.mysql.jdbc.Connection)c); |
790 | } |
791 | |
792 | return false; |
793 | } |
794 | |
795 | protected void close(boolean fireClosedEvent) throws SQLException { |
796 | synchronized (this.mpc) { |
797 | if (this.closed) { |
798 | return; |
799 | } |
800 | |
801 | if (!isInGlobalTx() |
802 | && this.mc.getRollbackOnPooledClose() |
803 | && !this.getAutoCommit()) { |
804 | rollback(); |
805 | } |
806 | |
807 | if (fireClosedEvent) { |
808 | this.mpc.callListener( |
809 | MysqlPooledConnection.CONNECTION_CLOSED_EVENT, null); |
810 | } |
811 | |
812 | // set closed status to true so that if application client tries to |
813 | // make additional |
814 | // calls a sqlException will be thrown. The physical connection is |
815 | // re-used by the pooled connection each time getConnection is |
816 | // called. |
817 | this.closed = true; |
818 | } |
819 | } |
820 | |
821 | private void checkClosed() throws SQLException { |
822 | if (this.closed) { |
823 | throw SQLError.createSQLException(this.invalidHandleStr); |
824 | } |
825 | } |
826 | |
827 | protected boolean isInGlobalTx() { |
828 | return this.mc.isInGlobalTx(); |
829 | } |
830 | |
831 | protected void setInGlobalTx(boolean flag) { |
832 | this.mc.setInGlobalTx(flag); |
833 | } |
834 | |
835 | public void ping() throws SQLException { |
836 | if (this.mc != null) { |
837 | this.mc.ping(); |
838 | } |
839 | } |
840 | } |