001: /*
002: * Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
003: * (http://h2database.com/html/license.html).
004: * Initial Developer: H2 Group
005: */
006: package org.h2.jdbc;
007:
008: import java.sql.BatchUpdateException;
009: import java.sql.Connection;
010: import java.sql.ResultSet;
011: import java.sql.SQLException;
012: import java.sql.SQLWarning;
013: import java.sql.Statement;
014:
015: import org.h2.command.CommandInterface;
016: import org.h2.constant.ErrorCode;
017: import org.h2.constant.SysProperties;
018: import org.h2.engine.SessionInterface;
019: import org.h2.message.Message;
020: import org.h2.message.TraceObject;
021: import org.h2.result.ResultInterface;
022: import org.h2.util.ObjectArray;
023:
024: /**
025: * Represents a statement.
026: */
027: public class JdbcStatement extends TraceObject implements Statement {
028:
029: protected JdbcConnection conn;
030: protected SessionInterface session;
031: protected JdbcResultSet resultSet;
032: protected int maxRows;
033: protected boolean escapeProcessing = true;
034: protected int fetchSize = SysProperties.SERVER_RESULT_SET_FETCH_SIZE;
035: protected int updateCount;
036: private CommandInterface executingCommand;
037: private ObjectArray batchCommands;
038: protected int resultSetType;
039: protected boolean closedByResultSet;
040:
041: /**
042: * Executes a query (select statement) and returns the result set.
043: * If another result set exists for this statement, this will be closed
044: * (even if this statement fails).
045: *
046: * @return the result set
047: */
048: public ResultSet executeQuery(String sql) throws SQLException {
049: try {
050: int id = getNextId(TraceObject.RESULT_SET);
051: if (debug()) {
052: debugCodeAssign("ResultSet", TraceObject.RESULT_SET,
053: id, "executeQuery(" + quote(sql) + ")");
054: }
055: checkClosed();
056: closeOld();
057: if (escapeProcessing) {
058: sql = conn.translateSQL(sql);
059: }
060: synchronized (session) {
061: CommandInterface command = conn.prepareCommand(sql,
062: fetchSize);
063: ResultInterface result;
064: boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY;
065: setExecutingStatement(command);
066: try {
067: result = command.executeQuery(maxRows, scrollable);
068: } finally {
069: setExecutingStatement(null);
070: }
071: command.close();
072: resultSet = new JdbcResultSet(session, conn, this ,
073: result, id, closedByResultSet, scrollable);
074: }
075: return resultSet;
076: } catch (Throwable e) {
077: throw logAndConvert(e);
078: }
079: }
080:
081: /**
082: * Executes a statement (insert, update, delete, create, drop)
083: * and returns the update count.
084: * If another result set exists for this statement, this will be closed
085: * (even if this statement fails).
086: *
087: * If the statement is a create or drop and does not throw an exception,
088: * the current transaction (if any) is committed after executing the statement.
089: * If auto commit is on, this statement will be committed.
090: *
091: * @param sql the SQL statement
092: * @return the update count (number of row affected by an insert,
093: * update or delete, or 0 if no rows or the statement was a
094: * create, drop, commit or rollback)
095: * @throws SQLException if a database error occurred or a
096: * select statement was executed
097: */
098: public int executeUpdate(String sql) throws SQLException {
099: try {
100: debugCodeCall("executeUpdate", sql);
101: checkClosed();
102: closeOld();
103: if (escapeProcessing) {
104: sql = conn.translateSQL(sql);
105: }
106: CommandInterface command = conn.prepareCommand(sql,
107: fetchSize);
108: synchronized (session) {
109: setExecutingStatement(command);
110: try {
111: updateCount = command.executeUpdate();
112: } finally {
113: setExecutingStatement(null);
114: }
115: }
116: command.close();
117: return updateCount;
118: } catch (Throwable e) {
119: throw logAndConvert(e);
120: }
121: }
122:
123: /**
124: * Executes an arbitrary statement. If another result set exists for this
125: * statement, this will be closed (even if this statement fails).
126: *
127: * If the statement is a create or drop and does not throw an exception, the
128: * current transaction (if any) is committed after executing the statement.
129: * If auto commit is on, and the statement is not a select, this statement
130: * will be committed.
131: *
132: * @return true if a result set is available, false if not
133: */
134: public boolean execute(String sql) throws SQLException {
135: try {
136: int id = getNextId(TraceObject.RESULT_SET);
137: if (debug()) {
138: debugCodeCall("execute", sql);
139: }
140: checkClosed();
141: closeOld();
142: if (escapeProcessing) {
143: sql = conn.translateSQL(sql);
144: }
145: CommandInterface command = conn.prepareCommand(sql,
146: fetchSize);
147: boolean returnsResultSet;
148: synchronized (session) {
149: setExecutingStatement(command);
150: try {
151: if (command.isQuery()) {
152: returnsResultSet = true;
153: boolean scrollable = resultSetType != ResultSet.TYPE_FORWARD_ONLY;
154: ResultInterface result = command.executeQuery(
155: maxRows, scrollable);
156: resultSet = new JdbcResultSet(session, conn,
157: this , result, id, closedByResultSet,
158: scrollable);
159: } else {
160: returnsResultSet = false;
161: updateCount = command.executeUpdate();
162: }
163: } finally {
164: setExecutingStatement(null);
165: }
166: }
167: command.close();
168: return returnsResultSet;
169: } catch (Throwable e) {
170: throw logAndConvert(e);
171: }
172: }
173:
174: /**
175: * Returns the last result set produces by this statement.
176: *
177: * @return the result set
178: */
179: public ResultSet getResultSet() throws SQLException {
180: try {
181: checkClosed();
182: if (resultSet != null) {
183: int id = resultSet.getTraceId();
184: debugCodeAssign("ResultSet", TraceObject.RESULT_SET,
185: id, "getResultSet()");
186: } else {
187: debugCodeCall("getResultSet");
188: }
189: return resultSet;
190: } catch (Throwable e) {
191: throw logAndConvert(e);
192: }
193: }
194:
195: /**
196: * Returns the last update count of this statement.
197: *
198: * @return the update count (number of row affected by an insert,
199: * update or delete, or 0 if no rows or the statement was a
200: * create, drop, commit or rollback; -1 if the statement was a select).
201: * @throws SQLException if this object is closed or invalid
202: */
203: public int getUpdateCount() throws SQLException {
204: try {
205: debugCodeCall("getUpdateCount");
206: checkClosed();
207: return updateCount;
208: } catch (Throwable e) {
209: throw logAndConvert(e);
210: }
211: }
212:
213: /**
214: * Closes this statement.
215: * All result sets that where created by this statement
216: * become invalid after calling this method.
217: */
218: public void close() throws SQLException {
219: try {
220: debugCodeCall("close");
221: closeOld();
222: if (conn != null) {
223: conn = null;
224: }
225: } catch (Throwable e) {
226: throw logAndConvert(e);
227: }
228: }
229:
230: /**
231: * Returns the connection that created this object.
232: *
233: * @return the connection
234: */
235: public Connection getConnection() throws SQLException {
236: try {
237: debugCodeCall("getConnection");
238: checkClosed();
239: return conn;
240: } catch (Throwable e) {
241: throw logAndConvert(e);
242: }
243: }
244:
245: /**
246: * Gets the first warning reported by calls on this object.
247: * This driver does not support warnings, and will always return null.
248: *
249: * @return null
250: */
251: public SQLWarning getWarnings() throws SQLException {
252: try {
253: debugCodeCall("getWarnings");
254: checkClosed();
255: return null;
256: } catch (Throwable e) {
257: throw logAndConvert(e);
258: }
259: }
260:
261: /**
262: * Clears all warnings. As this driver does not support warnings,
263: * this call is ignored.
264: */
265: public void clearWarnings() throws SQLException {
266: try {
267: debugCodeCall("clearWarnings");
268: checkClosed();
269: } catch (Throwable e) {
270: throw logAndConvert(e);
271: }
272: }
273:
274: /**
275: * Moves to the next result set - however there is always only one result
276: * set. This call also closes the current result set (if there is one).
277: * Returns true if there is a next result set (that means - it always
278: * returns false).
279: *
280: * @return false
281: * @throws SQLException if this object is closed.
282: */
283: public boolean getMoreResults() throws SQLException {
284: try {
285: debugCodeCall("getMoreResults");
286: checkClosed();
287: closeOld();
288: return false;
289: } catch (Throwable e) {
290: throw logAndConvert(e);
291: }
292: }
293:
294: /**
295: * Sets the name of the cursor. This call is ignored.
296: *
297: * @param name ignored
298: * @throws SQLException if this object is closed
299: */
300: public void setCursorName(String name) throws SQLException {
301: try {
302: debugCodeCall("setCursorName", name);
303: checkClosed();
304: } catch (Throwable e) {
305: throw logAndConvert(e);
306: }
307: }
308:
309: /**
310: * Sets the fetch direction.
311: * This call is ignored by this driver.
312: *
313: * @param direction ignored
314: * @throws SQLException if this object is closed
315: */
316: public void setFetchDirection(int direction) throws SQLException {
317: try {
318: debugCodeCall("setFetchDirection", direction);
319: checkClosed();
320: } catch (Throwable e) {
321: throw logAndConvert(e);
322: }
323: }
324:
325: /**
326: * Gets the fetch direction.
327: *
328: * @return FETCH_FORWARD
329: * @throws SQLException if this object is closed
330: */
331: public int getFetchDirection() throws SQLException {
332: try {
333: debugCodeCall("getFetchDirection");
334: checkClosed();
335: return ResultSet.FETCH_FORWARD;
336: } catch (Throwable e) {
337: throw logAndConvert(e);
338: }
339: }
340:
341: /**
342: * Gets the maximum number of rows for a ResultSet.
343: *
344: * @return the number of rows where 0 means no limit
345: * @throws SQLException if this object is closed
346: */
347: public int getMaxRows() throws SQLException {
348: try {
349: debugCodeCall("getMaxRows");
350: checkClosed();
351: return maxRows;
352: } catch (Throwable e) {
353: throw logAndConvert(e);
354: }
355: }
356:
357: /**
358: * Gets the maximum number of rows for a ResultSet.
359: *
360: * @param maxRows the number of rows where 0 means no limit
361: * @throws SQLException if this object is closed
362: */
363: public void setMaxRows(int maxRows) throws SQLException {
364: try {
365: debugCodeCall("setMaxRows", maxRows);
366: checkClosed();
367: if (maxRows < 0) {
368: throw Message.getInvalidValueException("" + maxRows,
369: "maxRows");
370: }
371: this .maxRows = maxRows;
372: } catch (Throwable e) {
373: throw logAndConvert(e);
374: }
375: }
376:
377: /**
378: * Sets the number of rows suggested to read in one step.
379: * This value cannot be higher than the maximum rows (setMaxRows)
380: * set by the statement or prepared statement, otherwise an exception
381: * is throws. Setting the value to 0 will set the default value.
382: * The default value can be changed using the system property
383: * h2.serverResultSetFetchSize.
384: *
385: * @param rows the number of rows
386: * @throws SQLException if this object is closed
387: */
388: public void setFetchSize(int rows) throws SQLException {
389: try {
390: debugCodeCall("setFetchSize", rows);
391: checkClosed();
392: if (rows < 0 || (rows > 0 && maxRows > 0 && rows > maxRows)) {
393: throw Message.getInvalidValueException("" + rows,
394: "rows");
395: }
396: if (rows == 0) {
397: rows = SysProperties.SERVER_RESULT_SET_FETCH_SIZE;
398: }
399: fetchSize = rows;
400: } catch (Throwable e) {
401: throw logAndConvert(e);
402: }
403: }
404:
405: /**
406: * Gets the number of rows suggested to read in one step.
407: *
408: * @return the current fetch size
409: * @throws SQLException if this object is closed
410: */
411: public int getFetchSize() throws SQLException {
412: try {
413: debugCodeCall("getFetchSize");
414: checkClosed();
415: return fetchSize;
416: } catch (Throwable e) {
417: throw logAndConvert(e);
418: }
419: }
420:
421: /**
422: * Gets the result set concurrency created by this object.
423: *
424: * @return ResultSet.CONCUR_UPDATABLE
425: * @throws SQLException if this object is closed
426: */
427: public int getResultSetConcurrency() throws SQLException {
428: try {
429: debugCodeCall("getResultSetConcurrency");
430: checkClosed();
431: return ResultSet.CONCUR_UPDATABLE;
432: } catch (Throwable e) {
433: throw logAndConvert(e);
434: }
435: }
436:
437: /**
438: * Gets the result set type.
439: *
440: * @return the type
441: * @throws SQLException if this object is closed
442: */
443: public int getResultSetType() throws SQLException {
444: try {
445: debugCodeCall("getResultSetType");
446: checkClosed();
447: return resultSetType;
448: } catch (Throwable e) {
449: throw logAndConvert(e);
450: }
451: }
452:
453: /**
454: * Gets the maximum number of bytes for a result set column.
455: *
456: * @return always 0 for no limit
457: * @throws SQLException if this object is closed
458: */
459: public int getMaxFieldSize() throws SQLException {
460: try {
461: debugCodeCall("getMaxFieldSize");
462: checkClosed();
463: return 0;
464: } catch (Throwable e) {
465: throw logAndConvert(e);
466: }
467: }
468:
469: /**
470: * Sets the maximum number of bytes for a result set column.
471: * This method does currently do nothing for this driver.
472: *
473: * @param max the maximum size - ignored
474: * @throws SQLException if this object is closed
475: */
476: public void setMaxFieldSize(int max) throws SQLException {
477: try {
478: debugCodeCall("setMaxFieldSize", max);
479: checkClosed();
480: } catch (Throwable e) {
481: throw logAndConvert(e);
482: }
483: }
484:
485: /**
486: * Enables or disables processing or JDBC escape syntax.
487: * See also Connection.nativeSQL.
488: *
489: * @param enable - true (default) or false (no conversion is attempted)
490: * @throws SQLException if this object is closed
491: */
492: public void setEscapeProcessing(boolean enable) throws SQLException {
493: try {
494: if (debug()) {
495: debugCode("setEscapeProcessing(" + enable + ");");
496: }
497: checkClosed();
498: escapeProcessing = enable;
499: } catch (Throwable e) {
500: throw logAndConvert(e);
501: }
502: }
503:
504: /**
505: * [Partially supported] Cancels a currently running statement.
506: * This method must be called from within another
507: * thread than the execute method.
508: * This method is not supported in the server mode.
509: *
510: * @throws SQLException if this object is closed
511: */
512: public void cancel() throws SQLException {
513: try {
514: debugCodeCall("cancel");
515: checkClosed();
516: // executingCommand can be reset by another thread
517: CommandInterface c = executingCommand;
518: try {
519: if (c != null) {
520: c.cancel();
521: }
522: } finally {
523: setExecutingStatement(null);
524: }
525: } catch (Throwable e) {
526: throw logAndConvert(e);
527: }
528: }
529:
530: /**
531: * Gets the current query timeout in seconds.
532: * This method will return 0 if no query timeout is set.
533: * The result is rounded to the next second.
534: *
535: * @return the timeout in seconds
536: * @throws SQLException if this object is closed
537: */
538: public int getQueryTimeout() throws SQLException {
539: try {
540: debugCodeCall("getQueryTimeout");
541: checkClosed();
542: return conn.getQueryTimeout();
543: } catch (Throwable e) {
544: throw logAndConvert(e);
545: }
546: }
547:
548: /**
549: * Sets the current query timeout in seconds. Calling this method will
550: * commit an open transaction, even if the value is the same as before.
551: * Changing the value will affect all statements of this connection.
552: *
553: * @param seconds the timeout in seconds - 0 means no timeout, values
554: * smaller 0 will throw an exception
555: * @throws SQLException if this object is closed
556: */
557: public void setQueryTimeout(int seconds) throws SQLException {
558: try {
559: debugCodeCall("setQueryTimeout", seconds);
560: checkClosed();
561: if (seconds < 0) {
562: throw Message.getInvalidValueException("" + seconds,
563: "seconds");
564: }
565: conn.setQueryTimeout(seconds);
566: } catch (Throwable e) {
567: throw logAndConvert(e);
568: }
569: }
570:
571: /**
572: * Adds a statement to the batch.
573: */
574: public void addBatch(String sql) throws SQLException {
575: try {
576: debugCodeCall("addBatch", sql);
577: checkClosed();
578: if (escapeProcessing) {
579: sql = conn.translateSQL(sql);
580: }
581: if (batchCommands == null) {
582: batchCommands = new ObjectArray();
583: }
584: batchCommands.add(sql);
585: } catch (Throwable e) {
586: throw logAndConvert(e);
587: }
588: }
589:
590: /**
591: * Clears the batch.
592: */
593: public void clearBatch() throws SQLException {
594: try {
595: debugCodeCall("clearBatch");
596: checkClosed();
597: batchCommands = null;
598: } catch (Throwable e) {
599: throw logAndConvert(e);
600: }
601: }
602:
603: /**
604: * Executes the batch.
605: *
606: * @return the array of update counts
607: */
608: public int[] executeBatch() throws SQLException {
609: try {
610: debugCodeCall("executeBatch");
611: checkClosed();
612: if (batchCommands == null) {
613: // TODO batch: check what other database do if no commands are set
614: batchCommands = new ObjectArray();
615: }
616: int[] result = new int[batchCommands.size()];
617: boolean error = false;
618: for (int i = 0; i < batchCommands.size(); i++) {
619: String sql = (String) batchCommands.get(i);
620: try {
621: result[i] = executeUpdate(sql);
622: } catch (SQLException e) {
623: logAndConvert(e);
624: //#ifdef JDK14
625: result[i] = Statement.EXECUTE_FAILED;
626: //#endif
627: error = true;
628: }
629: }
630: batchCommands = null;
631: if (error) {
632: throw new BatchUpdateException(result);
633: }
634: return result;
635: } catch (Throwable e) {
636: throw logAndConvert(e);
637: }
638: }
639:
640: /**
641: * Return a result set that contains the last generated autoincrement key
642: * for this connection.
643: *
644: * @return the result set with one row and one column containing the key
645: * @throws SQLException if this object is closed
646: */
647: public ResultSet getGeneratedKeys() throws SQLException {
648: try {
649: int id = getNextId(TraceObject.RESULT_SET);
650: if (debug()) {
651: debugCodeAssign("ResultSet", TraceObject.RESULT_SET,
652: id, "getGeneratedKeys()");
653: }
654: checkClosed();
655: ResultInterface result = conn.getGeneratedKeys(this , id);
656: ResultSet rs = new JdbcResultSet(session, conn, this ,
657: result, id, false, true);
658: return rs;
659: } catch (Throwable e) {
660: throw logAndConvert(e);
661: }
662: }
663:
664: /**
665: * [Not supported]
666: */
667: public boolean getMoreResults(int current) throws SQLException {
668: try {
669: debugCodeCall("getMoreResults");
670: throw Message.getUnsupportedException();
671: } catch (Throwable e) {
672: throw logAndConvert(e);
673: }
674: }
675:
676: /**
677: * Executes a statement and returns the update count.
678: * This method just calls executeUpdate(String sql).
679: *
680: * @param sql the SQL statement
681: * @return the update count (number of row affected by an insert,
682: * update or delete, or 0 if no rows or the statement was a
683: * create, drop, commit or rollback)
684: * @throws SQLException if a database error occurred or a
685: * select statement was executed
686: */
687: public int executeUpdate(String sql, int autoGeneratedKeys)
688: throws SQLException {
689: try {
690: if (debug()) {
691: debugCode("executeUpdate(" + quote(sql) + ", "
692: + autoGeneratedKeys + ");");
693: }
694: return executeUpdate(sql);
695: } catch (Throwable e) {
696: throw logAndConvert(e);
697: }
698: }
699:
700: /**
701: * Executes a statement and returns the update count.
702: * This method just calls executeUpdate(String sql).
703: *
704: * @param sql the SQL statement
705: * @return the update count (number of row affected by an insert,
706: * update or delete, or 0 if no rows or the statement was a
707: * create, drop, commit or rollback)
708: * @throws SQLException if a database error occurred or a
709: * select statement was executed
710: */
711: public int executeUpdate(String sql, int[] columnIndexes)
712: throws SQLException {
713: try {
714: if (debug()) {
715: debugCode("executeUpdate(" + quote(sql) + ", "
716: + quoteIntArray(columnIndexes) + ");");
717: }
718: return executeUpdate(sql);
719: } catch (Throwable e) {
720: throw logAndConvert(e);
721: }
722: }
723:
724: /**
725: * Executes a statement and returns the update count.
726: * This method just calls executeUpdate(String sql).
727: *
728: * @param sql the SQL statement
729: * @return the update count (number of row affected by an insert,
730: * update or delete, or 0 if no rows or the statement was a
731: * create, drop, commit or rollback)
732: * @throws SQLException if a database error occurred or a
733: * select statement was executed
734: */
735: public int executeUpdate(String sql, String[] columnNames)
736: throws SQLException {
737: try {
738: if (debug()) {
739: debugCode("executeUpdate(" + quote(sql) + ", "
740: + quoteArray(columnNames) + ");");
741: }
742: return executeUpdate(sql);
743: } catch (Throwable e) {
744: throw logAndConvert(e);
745: }
746: }
747:
748: /**
749: * Executes a statement and returns the update count.
750: * This method just calls execute(String sql).
751: *
752: * @param sql the SQL statement
753: * @return the update count (number of row affected by an insert,
754: * update or delete, or 0 if no rows or the statement was a
755: * create, drop, commit or rollback)
756: * @throws SQLException if a database error occurred or a
757: * select statement was executed
758: */
759: public boolean execute(String sql, int autoGeneratedKeys)
760: throws SQLException {
761: try {
762: if (debug()) {
763: debugCode("execute(" + quote(sql) + ", "
764: + autoGeneratedKeys + ");");
765: }
766: return execute(sql);
767: } catch (Throwable e) {
768: throw logAndConvert(e);
769: }
770: }
771:
772: /**
773: * Executes a statement and returns the update count.
774: * This method just calls execute(String sql).
775: *
776: * @param sql the SQL statement
777: * @return the update count (number of row affected by an insert,
778: * update or delete, or 0 if no rows or the statement was a
779: * create, drop, commit or rollback)
780: * @throws SQLException if a database error occurred or a
781: * select statement was executed
782: */
783: public boolean execute(String sql, int[] columnIndexes)
784: throws SQLException {
785: try {
786: if (debug()) {
787: debugCode("execute(" + quote(sql) + ", "
788: + quoteIntArray(columnIndexes) + ");");
789: }
790: return execute(sql);
791: } catch (Throwable e) {
792: throw logAndConvert(e);
793: }
794: }
795:
796: /**
797: * Executes a statement and returns the update count.
798: * This method just calls execute(String sql).
799: *
800: * @param sql the SQL statement
801: * @return the update count (number of row affected by an insert,
802: * update or delete, or 0 if no rows or the statement was a
803: * create, drop, commit or rollback)
804: * @throws SQLException if a database error occurred or a
805: * select statement was executed
806: */
807: public boolean execute(String sql, String[] columnNames)
808: throws SQLException {
809: try {
810: if (debug()) {
811: debugCode("execute(" + quote(sql) + ", "
812: + quoteArray(columnNames) + ");");
813: }
814: return execute(sql);
815: } catch (Throwable e) {
816: throw logAndConvert(e);
817: }
818: }
819:
820: /**
821: * Gets the result set holdability.
822: *
823: * @return the holdability
824: */
825: //#ifdef JDK14
826: public int getResultSetHoldability() throws SQLException {
827: try {
828: debugCodeCall("getResultSetHoldability");
829: checkClosed();
830: return ResultSet.HOLD_CURSORS_OVER_COMMIT;
831: } catch (Throwable e) {
832: throw logAndConvert(e);
833: }
834: }
835:
836: //#endif
837:
838: // =============================================================
839:
840: JdbcStatement(SessionInterface session, JdbcConnection conn,
841: int resultSetType, int id, boolean closeWithResultSet) {
842: setTrace(session.getTrace(), TraceObject.STATEMENT, id);
843: this .session = session;
844: this .conn = conn;
845: this .resultSetType = resultSetType;
846: this .closedByResultSet = closeWithResultSet;
847: }
848:
849: void checkClosed() throws SQLException {
850: if (conn == null) {
851: throw Message.getSQLException(ErrorCode.OBJECT_CLOSED);
852: }
853: conn.checkClosed();
854: }
855:
856: void closeOld() throws SQLException {
857: try {
858: if (!closedByResultSet) {
859: if (resultSet != null) {
860: resultSet.closeInternal();
861: }
862: }
863: } finally {
864: resultSet = null;
865: updateCount = -1;
866: }
867: }
868:
869: protected void setExecutingStatement(CommandInterface c) {
870: conn.setExecutingStatement(c == null ? null : this );
871: executingCommand = c;
872: }
873:
874: /**
875: * Returns whether this statement is closed.
876: *
877: * @return true if the statement is closed
878: */
879: public boolean isClosed() throws SQLException {
880: try {
881: debugCodeCall("isClosed");
882: return conn == null;
883: } catch (Throwable e) {
884: throw logAndConvert(e);
885: }
886: }
887:
888: /**
889: * [Not supported] Return an object of this class if possible.
890: */
891: //#ifdef JDK16
892: /*
893: public <T> T unwrap(Class<T> iface) throws SQLException {
894: throw Message.getUnsupportedException();
895: }
896: */
897: //#endif
898: /**
899: * [Not supported] Checks if unwrap can return an object of this class.
900: */
901: //#ifdef JDK16
902: /*
903: public boolean isWrapperFor(Class< ? > iface) throws SQLException {
904: throw Message.getUnsupportedException();
905: }
906: */
907: //#endif
908: /**
909: * Returns whether this object is poolable.
910: * @return false
911: */
912: public boolean isPoolable() throws SQLException {
913: debugCodeCall("isPoolable");
914: return false;
915: }
916:
917: /**
918: * Requests that this object should be pooled or not.
919: * This call is ignored.
920: *
921: * @param poolable the requested value
922: */
923: public void setPoolable(boolean poolable) throws SQLException {
924: if (debug()) {
925: debugCode("setPoolable(" + poolable + ");");
926: }
927: }
928:
929: /**
930: * INTERNAL
931: */
932: public String toString() {
933: return getTraceObjectName();
934: }
935:
936: }
|