001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.sql;
030:
031: import com.caucho.log.Log;
032: import com.caucho.util.L10N;
033:
034: import java.sql.Connection;
035: import java.sql.ResultSet;
036: import java.sql.SQLException;
037: import java.sql.SQLWarning;
038: import java.sql.Statement;
039: import java.util.logging.Logger;
040:
041: /**
042: * User-view of a statement;
043: */
044: public class UserStatement implements Statement {
045: protected final static Logger log = Log.open(UserStatement.class);
046: protected final static L10N L = new L10N(UserStatement.class);
047:
048: // The connection
049: protected UserConnection _conn;
050:
051: // The underlying connection
052: protected Statement _stmt;
053:
054: // True if the statement is changed in a way that forbids its caching.
055: protected boolean _isPoolable = true;
056:
057: UserStatement(UserConnection conn, Statement stmt) {
058: _conn = conn;
059: _stmt = stmt;
060: }
061:
062: public void setPoolable(boolean poolable) throws SQLException {
063: if (!poolable)
064: _isPoolable = false;
065: }
066:
067: public boolean isPoolable() throws SQLException {
068: return _isPoolable;
069: }
070:
071: /**
072: * Returns the underlying statement.
073: */
074: public Statement getStatement() {
075: Statement stmt = _stmt;
076:
077: if (stmt instanceof com.caucho.sql.spy.SpyStatement) {
078: stmt = ((com.caucho.sql.spy.SpyStatement) stmt)
079: .getStatement();
080: }
081:
082: return stmt;
083: }
084:
085: public void addBatch(String sql) throws SQLException {
086: try {
087: _stmt.addBatch(sql);
088: } catch (RuntimeException e) {
089: killPool();
090: throw e;
091: } catch (SQLException e) {
092: killPool();
093: throw e;
094: }
095: }
096:
097: public void cancel() throws SQLException {
098: try {
099: _stmt.cancel();
100: } catch (RuntimeException e) {
101: killPool();
102: throw e;
103: } catch (SQLException e) {
104: killPool();
105: throw e;
106: }
107: }
108:
109: public void clearBatch() throws SQLException {
110: try {
111: _stmt.clearBatch();
112: } catch (RuntimeException e) {
113: killPool();
114: throw e;
115: } catch (SQLException e) {
116: killPool();
117: throw e;
118: }
119: }
120:
121: public void clearWarnings() throws SQLException {
122: try {
123: Statement stmt = _stmt;
124:
125: if (stmt != null)
126: stmt.clearWarnings();
127: } catch (RuntimeException e) {
128: killPool();
129: throw e;
130: } catch (SQLException e) {
131: killPool();
132: throw e;
133: }
134: }
135:
136: /**
137: * Closes the statement.
138: */
139: public void close() throws SQLException {
140: try {
141: Statement stmt = _stmt;
142: _stmt = null;
143:
144: if (stmt != null) {
145: _conn.closeStatement(stmt);
146:
147: stmt.close();
148: }
149: } catch (RuntimeException e) {
150: killPool();
151: throw e;
152: } catch (SQLException e) {
153: killPool();
154: throw e;
155: }
156: }
157:
158: /**
159: * queries the database with the given sql.
160: */
161: public ResultSet executeQuery(String sql) throws SQLException {
162: try {
163: return _stmt.executeQuery(sql);
164: } catch (RuntimeException e) {
165: killPool();
166: throw e;
167: } catch (SQLException e) {
168: killPool();
169: throw e;
170: }
171: }
172:
173: /**
174: * updates the database with the given sql.
175: */
176: public int executeUpdate(String sql) throws SQLException {
177: try {
178: return _stmt.executeUpdate(sql);
179: } catch (RuntimeException e) {
180: killPool();
181: throw e;
182: } catch (SQLException e) {
183: killPool();
184: throw e;
185: }
186: }
187:
188: /**
189: * Execute an update with the given result type.
190: */
191: public int executeUpdate(String query, int resultType)
192: throws SQLException {
193: try {
194: return _stmt.executeUpdate(query, resultType);
195: } catch (RuntimeException e) {
196: killPool();
197: throw e;
198: } catch (SQLException e) {
199: killPool();
200: throw e;
201: }
202: }
203:
204: /**
205: * Execute an update checking the given columns for primary keys.
206: */
207: public int executeUpdate(String query, int[] columns)
208: throws SQLException {
209: try {
210: return _stmt.executeUpdate(query, columns);
211: } catch (RuntimeException e) {
212: killPool();
213: throw e;
214: } catch (SQLException e) {
215: killPool();
216: throw e;
217: }
218: }
219:
220: /**
221: * Execute an update checking the given columns for primary keys.
222: */
223: public int executeUpdate(String query, String[] columns)
224: throws SQLException {
225: try {
226: return _stmt.executeUpdate(query, columns);
227: } catch (RuntimeException e) {
228: killPool();
229: throw e;
230: } catch (SQLException e) {
231: killPool();
232: throw e;
233: }
234: }
235:
236: /**
237: * executes the given sql.
238: */
239: public boolean execute(String sql) throws SQLException {
240: try {
241: return _stmt.execute(sql);
242: } catch (RuntimeException e) {
243: killPool();
244: throw e;
245: } catch (SQLException e) {
246: killPool();
247: throw e;
248: }
249: }
250:
251: /**
252: * executes the given query with its result type.
253: */
254: public boolean execute(String query, int resultType)
255: throws SQLException {
256: try {
257: return _stmt.execute(query, resultType);
258: } catch (RuntimeException e) {
259: killPool();
260: throw e;
261: } catch (SQLException e) {
262: killPool();
263: throw e;
264: }
265: }
266:
267: /**
268: * executes the given query with the columns given for
269: * primary key generation.
270: */
271: public boolean execute(String query, int[] columns)
272: throws SQLException {
273: try {
274: return _stmt.execute(query, columns);
275: } catch (RuntimeException e) {
276: killPool();
277: throw e;
278: } catch (SQLException e) {
279: killPool();
280: throw e;
281: }
282: }
283:
284: /**
285: * executes the given query with the columns given for
286: * primary key generation.
287: */
288: public boolean execute(String query, String[] columns)
289: throws SQLException {
290: try {
291: return _stmt.execute(query, columns);
292: } catch (RuntimeException e) {
293: killPool();
294: throw e;
295: } catch (SQLException e) {
296: killPool();
297: throw e;
298: }
299: }
300:
301: /**
302: * Executes the batched sql.
303: */
304: public int[] executeBatch() throws SQLException {
305: try {
306: return _stmt.executeBatch();
307: } catch (RuntimeException e) {
308: killPool();
309: throw e;
310: } catch (SQLException e) {
311: killPool();
312: throw e;
313: }
314: }
315:
316: /**
317: * Returns the result set of the last query.
318: */
319: public java.sql.ResultSet getResultSet() throws SQLException {
320: try {
321: return _stmt.getResultSet();
322: } catch (RuntimeException e) {
323: killPool();
324: throw e;
325: } catch (SQLException e) {
326: killPool();
327: throw e;
328: }
329: }
330:
331: /**
332: * Returns the update count of the last query.
333: */
334: public int getUpdateCount() throws SQLException {
335: try {
336: return _stmt.getUpdateCount();
337: } catch (RuntimeException e) {
338: killPool();
339: throw e;
340: } catch (SQLException e) {
341: killPool();
342: throw e;
343: }
344: }
345:
346: /**
347: * Returns the underlying connection.
348: */
349: public Connection getConnection() throws SQLException {
350: return _conn;
351: }
352:
353: /**
354: * Returns the current fetch direction.
355: */
356: public int getFetchDirection() throws SQLException {
357: try {
358: return _stmt.getFetchDirection();
359: } catch (RuntimeException e) {
360: killPool();
361: throw e;
362: } catch (SQLException e) {
363: killPool();
364: throw e;
365: }
366: }
367:
368: /**
369: * Sets the fetch direction.
370: */
371: public void setFetchDirection(int direction) throws SQLException {
372: try {
373: setPoolable(false);
374:
375: _stmt.setFetchDirection(direction);
376: } catch (RuntimeException e) {
377: killPool();
378: throw e;
379: } catch (SQLException e) {
380: killPool();
381: throw e;
382: }
383: }
384:
385: /**
386: * Returns the fetch size.
387: */
388: public int getFetchSize() throws SQLException {
389: try {
390: return _stmt.getFetchSize();
391: } catch (RuntimeException e) {
392: killPool();
393: throw e;
394: } catch (SQLException e) {
395: killPool();
396: throw e;
397: }
398: }
399:
400: /**
401: * Sets the fetch size.
402: */
403: public void setFetchSize(int rows) throws SQLException {
404: try {
405: setPoolable(false);
406:
407: _stmt.setFetchSize(rows);
408: } catch (RuntimeException e) {
409: killPool();
410: throw e;
411: } catch (SQLException e) {
412: killPool();
413: throw e;
414: }
415: }
416:
417: /**
418: * Returns the maximum field size.
419: */
420: public int getMaxFieldSize() throws SQLException {
421: try {
422: return _stmt.getMaxFieldSize();
423: } catch (RuntimeException e) {
424: killPool();
425: throw e;
426: } catch (SQLException e) {
427: killPool();
428: throw e;
429: }
430: }
431:
432: /**
433: * Sets the maximum field size.
434: */
435: public void setMaxFieldSize(int max) throws SQLException {
436: try {
437: setPoolable(false);
438:
439: _stmt.setMaxFieldSize(max);
440: } catch (RuntimeException e) {
441: killPool();
442: throw e;
443: } catch (SQLException e) {
444: killPool();
445: throw e;
446: }
447: }
448:
449: /**
450: * Returns the maximum rows returned by a query.
451: */
452: public int getMaxRows() throws SQLException {
453: try {
454: return _stmt.getMaxRows();
455: } catch (RuntimeException e) {
456: killPool();
457: throw e;
458: } catch (SQLException e) {
459: killPool();
460: throw e;
461: }
462: }
463:
464: /**
465: * Sets the maximum rows returned by a query.
466: */
467: public void setMaxRows(int max) throws SQLException {
468: try {
469: setPoolable(false);
470:
471: _stmt.setMaxRows(max);
472: } catch (RuntimeException e) {
473: killPool();
474: throw e;
475: } catch (SQLException e) {
476: killPool();
477: throw e;
478: }
479: }
480:
481: /**
482: * Returns true if more results are available.
483: */
484: public boolean getMoreResults() throws SQLException {
485: try {
486: return _stmt.getMoreResults();
487: } catch (RuntimeException e) {
488: killPool();
489: throw e;
490: } catch (SQLException e) {
491: killPool();
492: throw e;
493: }
494: }
495:
496: /**
497: * Returns the current query timeout.
498: */
499: public int getQueryTimeout() throws SQLException {
500: try {
501: return _stmt.getQueryTimeout();
502: } catch (RuntimeException e) {
503: killPool();
504: throw e;
505: } catch (SQLException e) {
506: killPool();
507: throw e;
508: }
509: }
510:
511: /**
512: * Sets the query timeout.
513: */
514: public void setQueryTimeout(int seconds) throws SQLException {
515: try {
516: setPoolable(false);
517:
518: _stmt.setQueryTimeout(seconds);
519: } catch (RuntimeException e) {
520: killPool();
521: throw e;
522: } catch (SQLException e) {
523: killPool();
524: throw e;
525: }
526: }
527:
528: /**
529: * Returns the statement's result set concurrency setting.
530: */
531: public int getResultSetConcurrency() throws SQLException {
532: try {
533: return _stmt.getResultSetConcurrency();
534: } catch (RuntimeException e) {
535: killPool();
536: throw e;
537: } catch (SQLException e) {
538: killPool();
539: throw e;
540: }
541: }
542:
543: /**
544: * Returns the statement's result set type.
545: */
546: public int getResultSetType() throws SQLException {
547: try {
548: return _stmt.getResultSetType();
549: } catch (RuntimeException e) {
550: killPool();
551: throw e;
552: } catch (SQLException e) {
553: killPool();
554: throw e;
555: }
556: }
557:
558: /**
559: * Returns the current sql warnings.
560: */
561: public SQLWarning getWarnings() throws SQLException {
562: try {
563: return _stmt.getWarnings();
564: } catch (RuntimeException e) {
565: killPool();
566: throw e;
567: } catch (SQLException e) {
568: killPool();
569: throw e;
570: }
571: }
572:
573: /**
574: * Sets the current cursor name.
575: */
576: public void setCursorName(String name) throws SQLException {
577: try {
578: setPoolable(false);
579:
580: _stmt.setCursorName(name);
581: } catch (RuntimeException e) {
582: killPool();
583: throw e;
584: } catch (SQLException e) {
585: killPool();
586: throw e;
587: }
588: }
589:
590: /**
591: * Enables escape processing.
592: */
593: public void setEscapeProcessing(boolean enable) throws SQLException {
594: try {
595: setPoolable(false);
596:
597: _stmt.setEscapeProcessing(enable);
598: } catch (RuntimeException e) {
599: killPool();
600: throw e;
601: } catch (SQLException e) {
602: killPool();
603: throw e;
604: }
605: }
606:
607: /**
608: * Returns the next count results.
609: */
610: public boolean getMoreResults(int count) throws SQLException {
611: try {
612: return _stmt.getMoreResults(count);
613: } catch (RuntimeException e) {
614: killPool();
615: throw e;
616: } catch (SQLException e) {
617: killPool();
618: throw e;
619: }
620: }
621:
622: /**
623: * Returns the generated keys for the update.
624: */
625: public java.sql.ResultSet getGeneratedKeys() throws SQLException {
626: try {
627: return _stmt.getGeneratedKeys();
628: } catch (RuntimeException e) {
629: killPool();
630: throw e;
631: } catch (SQLException e) {
632: killPool();
633: throw e;
634: }
635: }
636:
637: /**
638: * Returns the result set holdability.
639: */
640: public int getResultSetHoldability() throws SQLException {
641: try {
642: return _stmt.getResultSetHoldability();
643: } catch (RuntimeException e) {
644: killPool();
645: throw e;
646: } catch (SQLException e) {
647: killPool();
648: throw e;
649: }
650: }
651:
652: public boolean isClosed() throws SQLException {
653: return _stmt == null;
654: }
655:
656: public <T> T unwrap(Class<T> iface) throws SQLException {
657: return (T) _stmt;
658: }
659:
660: public boolean isWrapperFor(Class<?> iface) throws SQLException {
661: return (iface.isAssignableFrom(_stmt.getClass()));
662: }
663:
664: /**
665: * Marks the connection as non-poolable. When the connection is closed,
666: * it will actually be closed, not returned to the idle pool.
667: */
668: protected void killPool() {
669: if (_conn != null)
670: _conn.killPool();
671: }
672:
673: public String toString() {
674: return "UserStatement[" + _stmt + "]";
675: }
676: }
|