1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package com.gargoylesoftware.base.resource.jdbc;
39
40 import com.gargoylesoftware.base.resource.ManagedResource;
41 import java.sql.CallableStatement;
42 import java.sql.Connection;
43 import java.sql.DatabaseMetaData;
44 import java.sql.PreparedStatement;
45 import java.sql.Savepoint;
46 import java.sql.SQLException;
47 import java.sql.SQLWarning;
48 import java.sql.Statement;
49 import java.util.ArrayList;
50 import java.util.Collections;
51 import java.util.Iterator;
52 import java.util.List;
53 import java.util.Map;
54
55 /***
56 * A wrapper for java.sql.Connection objects.<p>
57 *
58 * The contract with JDBC says that result sets must be closed before
59 * statements and statements must be closed before connections but java does
60 * not enforce this contract. It is quite possible to close a connection while
61 * statements and result sets are still open. While some database drivers
62 * handle this condition nicely, others will start failing in undefined ways
63 * when this happens.<p>
64 *
65 * This wrapper class is a solution to this problem. If the connection is only
66 * accessed through the wrapper then the wrapper will ensure that everything is
67 * closed in the correct order. It will also ensure that the various jdbc
68 * objects (connections, statements, result sets and metadata) cannot be used
69 * after they are closed.<p>
70 *
71 * This class was created for the {@link JDBCResourceFactory} but can be used
72 * by itself.
73 *
74 * @version $Revision: 1.5 $
75 * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
76 */
77 public final class ConnectionWrapper implements Connection, ManagedResource {
78
79 private Connection delegate_ = null;
80 private boolean isOpen_ = true;
81 private String resourceFactoryName_;
82
83 private final List openStatements_ = Collections.synchronizedList(new ArrayList());
84 private final List openDatabaseMetaData_ = Collections.synchronizedList(new ArrayList());
85
86
87 /***
88 * Create a new connection wrapper
89 *
90 * @param connection The connection that we are wrapping
91 */
92 public ConnectionWrapper( final Connection connection ) {
93 if( connection == null ) {
94 throw new NullPointerException();
95 }
96 delegate_ = connection;
97 }
98
99
100 /***
101 * Set the name of the factory that allocated this connection
102 *
103 * @param name The name of the factory
104 */
105 public final void setResourceFactoryName( final String name ) {
106 resourceFactoryName_ = name;
107 }
108
109
110 /***
111 * Sets this connection's auto-commit mode. If a connection is in
112 * auto-commit mode, then all its SQL statements will be executed and
113 * committed as individual transactions. Otherwise, its SQL statements are
114 * grouped into transactions that are terminated by a call to either the
115 * method <code>commit</code> or the method <code>rollback</code>. By
116 * default, new connections are in auto-commit mode. <p>
117 *
118 * The commit occurs when the statement completes or the next execute
119 * occurs, whichever comes first. In the case of statements returning a
120 * ResultSet, the statement completes when the last row of the ResultSet
121 * has been retrieved or the ResultSet has been closed. In advanced cases,
122 * a single statement may return multiple results as well as output
123 * parameter values. In these cases the commit occurs when all results and
124 * output parameter values have been retrieved.
125 *
126 * @param autoCommit true enables auto-commit; false disables auto-commit.
127 * @exception SQLException if a database access error occurs
128 */
129 public void setAutoCommit( boolean autoCommit )
130 throws SQLException {
131 checkConnection();
132 delegate_.setAutoCommit( autoCommit );
133 }
134
135
136 /***
137 * Puts this connection in read-only mode as a hint to enable database
138 * optimizations. <P>
139 *
140 * <B>Note:</B> This method cannot be called while in the middle of a
141 * transaction.
142 *
143 * @param readOnly true enables read-only mode; false disables read-only
144 * mode.
145 * @exception SQLException if a database access error occurs
146 */
147 public void setReadOnly( boolean readOnly )
148 throws SQLException {
149 checkConnection();
150 delegate_.setReadOnly( readOnly );
151 }
152
153
154 /***
155 * Sets a catalog name in order to select a subspace of this Connection's
156 * database in which to work. If the driver does not support catalogs, it
157 * will silently ignore this request.
158 *
159 * @param catalog The catalog name
160 * @exception SQLException if a database access error occurs
161 */
162 public void setCatalog( String catalog )
163 throws SQLException {
164 checkConnection();
165 delegate_.setCatalog( catalog );
166 }
167
168
169 /***
170 * Attempts to change the transaction isolation level to the one given. The
171 * constants defined in the interface <code>Connection</code> are the
172 * possible transaction isolation levels. <P>
173 *
174 * <B>Note:</B> This method cannot be called while in the middle of a
175 * transaction.
176 *
177 * @param level one of the TRANSACTION_* isolation values with the
178 * exception of TRANSACTION_NONE; some databases may not support other
179 * values
180 * @exception SQLException if a database access error occurs
181 */
182 public void setTransactionIsolation( int level )
183 throws SQLException {
184 checkConnection();
185 delegate_.setTransactionIsolation( level );
186 }
187
188
189 /***
190 * Installs the given type map as the type map for this connection. The
191 * type map will be used for the custom mapping of SQL structured types and
192 * distinct types.
193 *
194 * @param map the <code>java.util.Map</code> object to install as the
195 * replacement for this <code>Connection</code> object's default type
196 * map
197 * @exception SQLException If a sql error occurs
198 * @since 1.2
199 */
200 public void setTypeMap( final Map map )
201 throws SQLException {
202 checkConnection();
203 delegate_.setTypeMap( map );
204 }
205
206
207 /***
208 * Return the name of the factory that allocated this connection
209 *
210 * @return The name of the factory
211 */
212 public final String getResourceFactoryName() {
213 return resourceFactoryName_;
214 }
215
216
217 /***
218 * Return the wrapped connection
219 *
220 * @return The wrapped connection
221 */
222 public final Connection getDelegate() {
223 return delegate_;
224 }
225
226
227 /***
228 * Gets the current auto-commit state.
229 *
230 * @return the current state of auto-commit mode
231 * @exception SQLException if a database access error occurs
232 * @see #setAutoCommit
233 */
234 public boolean getAutoCommit()
235 throws SQLException {
236 checkConnection();
237 return delegate_.getAutoCommit();
238 }
239
240
241 /***
242 * Tests to see if a Connection is closed.
243 *
244 * @return true if the connection is closed; false if it's still open
245 * @exception SQLException if a database access error occurs
246 */
247 public boolean isClosed()
248 throws SQLException {
249
250 if( delegate_ == null ) {
251 return true;
252 }
253
254 return delegate_.isClosed();
255 }
256
257
258
259
260 /***
261 * Gets the metadata regarding this connection's database. A Connection's
262 * database is able to provide information describing its tables, its
263 * supported SQL grammar, its stored procedures, the capabilities of this
264 * connection, and so on. This information is made available through a
265 * DatabaseMetaData object.
266 *
267 * @return a DatabaseMetaData object for this Connection
268 * @exception SQLException if a database access error occurs
269 */
270 public DatabaseMetaData getMetaData()
271 throws SQLException {
272 checkConnection();
273 final DatabaseMetaDataWrapper wrapper
274 = new DatabaseMetaDataWrapper( delegate_.getMetaData() );
275 wrapper.setConnection( this );
276 openDatabaseMetaData_.add( wrapper );
277 return wrapper;
278 }
279
280
281 /***
282 * Tests to see if the connection is in read-only mode.
283 *
284 * @return true if connection is read-only and false otherwise
285 * @exception SQLException if a database access error occurs
286 */
287 public boolean isReadOnly()
288 throws SQLException {
289 checkConnection();
290 return delegate_.isReadOnly();
291 }
292
293
294 /***
295 * Returns the Connection's current catalog name.
296 *
297 * @return the current catalog name or null
298 * @exception SQLException if a database access error occurs
299 */
300 public String getCatalog()
301 throws SQLException {
302 checkConnection();
303 return delegate_.getCatalog();
304 }
305
306
307 /***
308 * Gets this Connection's current transaction isolation level.
309 *
310 * @return the current TRANSACTION_* mode value
311 * @exception SQLException if a database access error occurs
312 */
313 public int getTransactionIsolation()
314 throws SQLException {
315 checkConnection();
316 return delegate_.getTransactionIsolation();
317 }
318
319
320 /***
321 * Returns the first warning reported by calls on this Connection. <P>
322 *
323 * <B>Note:</B> Subsequent warnings will be chained to this SQLWarning.
324 *
325 * @return the first SQLWarning or null
326 * @exception SQLException if a database access error occurs
327 */
328 public SQLWarning getWarnings()
329 throws SQLException {
330 checkConnection();
331 return delegate_.getWarnings();
332 }
333
334
335 /***
336 * Gets the type map object associated with this connection. Unless the
337 * application has added an entry to the type map, the map returned will be
338 * empty.
339 *
340 * @return the <code>java.util.Map</code> object associated with this
341 * <code>Connection</code> object
342 * @exception SQLException If a sql error occurs
343 * @since 1.2
344 */
345 public Map getTypeMap()
346 throws SQLException {
347 checkConnection();
348 return delegate_.getTypeMap();
349 }
350
351
352 /***
353 * Creates a <code>Statement</code> object for sending SQL statements to
354 * the database. SQL statements without parameters are normally executed
355 * using Statement objects. If the same SQL statement is executed many
356 * times, it is more efficient to use a <code>PreparedStatement</code>
357 * object. <P>
358 *
359 * Result sets created using the returned <code>Statement</code> object
360 * will by default have forward-only type and read-only concurrency.
361 *
362 * @return a new Statement object
363 * @exception SQLException if a database access error occurs
364 */
365 public Statement createStatement()
366 throws SQLException {
367 checkConnection();
368 final StatementWrapper wrapper = new StatementWrapper( delegate_.createStatement() );
369 wrapper.setConnection( this );
370 openStatements_.add( wrapper );
371 return wrapper;
372 }
373
374
375 /***
376 * Creates a <code>PreparedStatement</code> object for sending
377 * parameterized SQL statements to the database. A SQL statement with or
378 * without IN parameters can be pre-compiled and stored in a
379 * PreparedStatement object. This object can then be used to efficiently
380 * execute this statement multiple times. <P>
381 *
382 * <B>Note:</B> This method is optimized for handling parametric SQL
383 * statements that benefit from precompilation. If the driver supports
384 * precompilation, the method <code>prepareStatement</code> will send the
385 * statement to the database for precompilation. Some drivers may not
386 * support precompilation. In this case, the statement may not be sent to
387 * the database until the <code>PreparedStatement</code> is executed. This
388 * has no direct effect on users; however, it does affect which method
389 * throws certain SQLExceptions. <p>
390 *
391 * Result sets created using the returned PreparedStatement will have
392 * forward-only type and read-only concurrency, by default.
393 *
394 * @param sql a SQL statement that may contain one or more '?' IN parameter
395 * placeholders
396 * @return a new PreparedStatement object containing the pre-compiled
397 * statement
398 * @exception SQLException if a database access error occurs
399 */
400 public PreparedStatement prepareStatement( String sql )
401 throws SQLException {
402 checkConnection();
403 final PreparedStatement statement = new PreparedStatementWrapper( delegate_.prepareStatement( sql ) );
404 openStatements_.add( statement );
405 return statement;
406 }
407
408
409 /***
410 * Creates a <code>CallableStatement</code> object for calling database
411 * stored procedures. The <code>CallableStatement</code> object provides
412 * methods for setting up its IN and OUT parameters, and methods for
413 * executing the call to a stored procedure. <P>
414 *
415 * <B>Note:</B> This method is optimized for handling stored procedure call
416 * statements. Some drivers may send the call statement to the database
417 * when the method <code>prepareCall</code> is done; others may wait until
418 * the <code>CallableStatement</code> object is executed. This has no
419 * direct effect on users; however, it does affect which method throws
420 * certain SQLExceptions. Result sets created using the returned
421 * CallableStatement will have forward-only type and read-only concurrency,
422 * by default.
423 *
424 * @param sql a SQL statement that may contain one or more '?' parameter
425 * placeholders. Typically this statement is a JDBC function call
426 * escape string.
427 * @return a new CallableStatement object containing the pre-compiled SQL
428 * statement
429 * @exception SQLException if a database access error occurs
430 */
431 public CallableStatement prepareCall( String sql )
432 throws SQLException {
433 checkConnection();
434 final CallableStatement statement
435 = new CallableStatementWrapper( delegate_.prepareCall( sql ) );
436 openStatements_.add( statement );
437 return statement;
438 }
439
440
441 /***
442 * Converts the given SQL statement into the system's native SQL grammar. A
443 * driver may convert the JDBC sql grammar into its system's native SQL
444 * grammar prior to sending it; this method returns the native form of the
445 * statement that the driver would have sent.
446 *
447 * @param sql a SQL statement that may contain one or more '?' parameter
448 * placeholders
449 * @return the native form of this statement
450 * @exception SQLException if a database access error occurs
451 */
452 public String nativeSQL( String sql )
453 throws SQLException {
454 checkConnection();
455 return delegate_.nativeSQL( sql );
456 }
457
458
459 /***
460 * Makes all changes made since the previous commit/rollback permanent and
461 * releases any database locks currently held by the Connection. This
462 * method should be used only when auto-commit mode has been disabled.
463 *
464 * @exception SQLException if a database access error occurs
465 * @see #setAutoCommit
466 */
467 public void commit()
468 throws SQLException {
469 checkConnection();
470 delegate_.commit();
471 }
472
473
474 /***
475 * Drops all changes made since the previous commit/rollback and releases
476 * any database locks currently held by this Connection. This method should
477 * be used only when auto- commit has been disabled.
478 *
479 * @exception SQLException if a database access error occurs
480 * @see #setAutoCommit
481 */
482 public void rollback()
483 throws SQLException {
484 checkConnection();
485 delegate_.rollback();
486 }
487
488
489 /***
490 * Releases a Connection's database and JDBC resources immediately instead
491 * of waiting for them to be automatically released. <P>
492 *
493 * <B>Note:</B> A Connection is automatically closed when it is garbage
494 * collected. Certain fatal errors also result in a closed Connection.
495 *
496 * @exception SQLException if a database access error occurs
497 */
498 public void close()
499 throws SQLException {
500 if( isOpen_ ) {
501 closeAnyOpenStatements();
502 closeAnyOpenMetaDatas();
503
504 delegate_.close();
505 delegate_ = null;
506 }
507 else {
508 throw new AlreadyClosedException( "Connection is closed" );
509 }
510 isOpen_ = false;
511 }
512
513
514 /***
515 * Close any open statements
516 *
517 * @exception SQLException If an error occurs
518 */
519 public void closeAnyOpenStatements()
520 throws SQLException {
521 StatementWrapper statement;
522 Iterator iterator = openStatements_.iterator();
523 while( iterator.hasNext() ) {
524 statement = ( StatementWrapper )iterator.next();
525 if( statement.isClosed() == false ) {
526 statement.close();
527 }
528 }
529 openStatements_.clear();
530 }
531
532
533 /***
534 * Close any open DatabaseMetaData objects
535 *
536 * @exception SQLException If an error occurs
537 */
538 public void closeAnyOpenMetaDatas()
539 throws SQLException {
540 final Iterator iterator = openDatabaseMetaData_.iterator();
541 while( iterator.hasNext() ) {
542 ( ( DatabaseMetaDataWrapper )iterator.next() ).close();
543 }
544 openDatabaseMetaData_.clear();
545 }
546
547
548 /***
549 * Clears all warnings reported for this <code>Connection</code> object.
550 * After a call to this method, the method <code>getWarnings</code> returns
551 * null until a new warning is reported for this Connection.
552 *
553 * @exception SQLException if a database access error occurs
554 */
555 public void clearWarnings()
556 throws SQLException {
557 checkConnection();
558 delegate_.clearWarnings();
559 }
560
561
562
563
564 /***
565 * Creates a <code>Statement</code> object that will generate <code>ResultSet</code>
566 * objects with the given type and concurrency. This method is the same as
567 * the <code>createStatement</code> method above, but it allows the default
568 * result set type and result set concurrency type to be overridden.
569 *
570 * @param resultSetType a result set type; see ResultSet.TYPE_XXX
571 * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX
572 * @return a new Statement object
573 * @exception SQLException if a database access error occurs
574 * @since 1.2
575 */
576 public Statement createStatement( int resultSetType, int resultSetConcurrency )
577 throws
578 SQLException {
579
580 checkConnection();
581 final StatementWrapper wrapper
582 = new StatementWrapper( delegate_.createStatement( resultSetType, resultSetConcurrency ) );
583 openStatements_.add( wrapper );
584 return wrapper;
585 }
586
587
588 /***
589 * Creates a <code>PreparedStatement</code> object that will generate
590 * <code>ResultSet</code> objects with the given type and concurrency. This
591 * method is the same as the <code>prepareStatement</code> method above,
592 * but it allows the default result set type and result set concurrency
593 * type to be overridden.
594 *
595 * @param sql a SQL statement that may contain one or more '?' parameter
596 * placeholders. Typically this statement is a JDBC function call
597 * escape string.
598 * @param resultSetType a result set type; see ResultSet.TYPE_XXX
599 * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX
600 * @return a new PreparedStatement object containing the pre-compiled SQL
601 * statement
602 * @exception SQLException if a database access error occurs
603 * @since 1.2
604 */
605 public PreparedStatement prepareStatement(
606 final String sql,
607 final int resultSetType,
608 final int resultSetConcurrency )
609 throws
610 SQLException {
611
612 checkConnection();
613 final PreparedStatement statement
614 = new PreparedStatementWrapper(
615 delegate_.prepareStatement( sql, resultSetType, resultSetConcurrency ) );
616 openStatements_.add( statement );
617 return statement;
618 }
619
620
621 /***
622 * Creates a <code>CallableStatement</code> object that will generate
623 * <code>ResultSet</code> objects with the given type and concurrency. This
624 * method is the same as the <code>prepareCall</code> method above, but it
625 * allows the default result set type and result set concurrency type to be
626 * overridden.
627 *
628 * @param sql a SQL statement that may contain one or more '?' parameter
629 * placeholders. Typically this statement is a JDBC function call
630 * escape string.
631 * @param resultSetType a result set type; see ResultSet.TYPE_XXX
632 * @param resultSetConcurrency a concurrency type; see ResultSet.CONCUR_XXX
633 * @return a new CallableStatement object containing the pre-compiled SQL
634 * statement
635 * @exception SQLException if a database access error occurs
636 * @since 1.2
637 */
638 public CallableStatement prepareCall( String sql, int resultSetType,
639 int resultSetConcurrency )
640 throws SQLException {
641 checkConnection();
642 final CallableStatement statement
643 = new CallableStatementWrapper( delegate_.prepareCall( sql, resultSetType, resultSetConcurrency ) );
644 openStatements_.add( statement );
645 return statement;
646 }
647
648
649 /***
650 * Check to see if the connection is still open. If not, throw an
651 * exception.
652 *
653 * @exception SQLException
654 */
655 private void checkConnection()
656 throws SQLException {
657 if( isOpen_ == false ) {
658 throw new SQLException( "Methods cannot be invoked on a closed connection" );
659 }
660 }
661
662
663 /***
664 * Return the number of statements that are currently open. Useful for debugging purposes.
665 *
666 * @return The number of statements that are currently open.
667 */
668 public int getOpenStatementCount() {
669 synchronized(openStatements_) {
670 int count = 0;
671 final Iterator iterator = openStatements_.iterator();
672 while( iterator.hasNext() ) {
673 final StatementWrapper statement = (StatementWrapper)iterator.next();
674 if( statement.isClosed() ) {
675 iterator.remove();
676 }
677 else {
678 count++;
679 }
680 }
681
682 return count;
683 }
684 }
685
686
687 /***
688 * Changes the holdability of <code>ResultSet</code> objects
689 * created using this <code>Connection</code> object to the given
690 * holdability.
691 *
692 * @param holdability a <code>ResultSet</code> holdability constant; one of
693 * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
694 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
695 * @throws SQLException if a database access occurs, the given parameter
696 * is not a <code>ResultSet</code> constant indicating holdability,
697 * or the given holdability is not supported
698 * @see #getHoldability
699 * @see java.sql.ResultSet
700 * @since 1.4
701 */
702 public void setHoldability(int holdability) throws SQLException {
703 checkConnection();
704 delegate_.setHoldability(holdability);
705 }
706
707
708 /***
709 * Retrieves the current holdability of <code>ResultSet</code> objects
710 * created using this <code>Connection</code> object.
711 *
712 * @return the holdability, one of
713 * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
714 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
715 * @throws SQLException if a database access occurs
716 * @see #setHoldability
717 * @see java.sql.ResultSet
718 * @since 1.4
719 */
720 public int getHoldability() throws SQLException {
721 checkConnection();
722 return delegate_.getHoldability();
723 }
724
725
726 /***
727 * Creates an unnamed savepoint in the current transaction and
728 * returns the new <code>Savepoint</code> object that represents it.
729 *
730 * @return the new <code>Savepoint</code> object
731 * @exception SQLException if a database access error occurs
732 * or this <code>Connection</code> object is currently in
733 * auto-commit mode
734 * @see Savepoint
735 * @since 1.4
736 */
737 public Savepoint setSavepoint() throws SQLException {
738 checkConnection();
739 return delegate_.setSavepoint();
740 }
741
742
743 /***
744 * Creates a savepoint with the given name in the current transaction
745 * and returns the new <code>Savepoint</code> object that represents it.
746 *
747 * @param name a <code>String</code> containing the name of the savepoint
748 * @return the new <code>Savepoint</code> object
749 * @exception SQLException if a database access error occurs
750 * or this <code>Connection</code> object is currently in
751 * auto-commit mode
752 * @see Savepoint
753 * @since 1.4
754 */
755 public Savepoint setSavepoint(String name) throws SQLException {
756 checkConnection();
757 return delegate_.setSavepoint(name);
758 }
759
760
761 /***
762 * Undoes all changes made after the given <code>Savepoint</code> object
763 * was set.
764 * <P>
765 * This method should be used only when auto-commit has been disabled.
766 *
767 * @param savepoint the <code>Savepoint</code> object to roll back to
768 * @exception SQLException if a database access error occurs,
769 * the <code>Savepoint</code> object is no longer valid,
770 * or this <code>Connection</code> object is currently in
771 * auto-commit mode
772 * @see Savepoint
773 * @since 1.4
774 */
775 public void rollback(Savepoint savepoint) throws SQLException {
776 checkConnection();
777 delegate_.rollback(savepoint);
778 }
779
780
781 /***
782 * Removes the given <code>Savepoint</code> object from the current
783 * transaction. Any reference to the savepoint after it have been removed
784 * will cause an <code>SQLException</code> to be thrown.
785 *
786 * @param savepoint the <code>Savepoint</code> object to be removed
787 * @exception SQLException if a database access error occurs or
788 * the given <code>Savepoint</code> object is not a valid
789 * savepoint in the current transaction
790 * @since 1.4
791 */
792 public void releaseSavepoint(Savepoint savepoint) throws SQLException {
793 checkConnection();
794 delegate_.releaseSavepoint(savepoint);
795 }
796
797
798 /***
799 * Creates a <code>Statement</code> object that will generate
800 * <code>ResultSet</code> objects with the given type, concurrency,
801 * and holdability.
802 * This method is the same as the <code>createStatement</code> method
803 * above, but it allows the default result set
804 * type, concurrency, and holdability to be overridden.
805 *
806 * @param resultSetType one of the following <code>ResultSet</code>
807 * constants:
808 * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
809 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
810 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
811 * @param resultSetConcurrency one of the following <code>ResultSet</code>
812 * constants:
813 * <code>ResultSet.CONCUR_READ_ONLY</code> or
814 * <code>ResultSet.CONCUR_UPDATABLE</code>
815 * @param resultSetHoldability one of the following <code>ResultSet</code>
816 * constants:
817 * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
818 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
819 * @return a new <code>Statement</code> object that will generate
820 * <code>ResultSet</code> objects with the given type,
821 * concurrency, and holdability
822 * @exception SQLException if a database access error occurs
823 * or the given parameters are not <code>ResultSet</code>
824 * constants indicating type, concurrency, and holdability
825 * @see java.sql.ResultSet
826 * @since 1.4
827 */
828 public Statement createStatement(int resultSetType, int resultSetConcurrency,
829 int resultSetHoldability) throws SQLException {
830 checkConnection();
831
832 final Statement statement = new StatementWrapper(
833 delegate_.createStatement( resultSetType, resultSetConcurrency, resultSetHoldability ) );
834 openStatements_.add( statement );
835 return statement;
836 }
837
838
839 /***
840 * Creates a <code>PreparedStatement</code> object that will generate
841 * <code>ResultSet</code> objects with the given type, concurrency,
842 * and holdability.
843 * <P>
844 * This method is the same as the <code>prepareStatement</code> method
845 * above, but it allows the default result set
846 * type, concurrency, and holdability to be overridden.
847 *
848 * @param sql a <code>String</code> object that is the SQL statement to
849 * be sent to the database; may contain one or more ? IN
850 * parameters
851 * @param resultSetType one of the following <code>ResultSet</code>
852 * constants:
853 * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
854 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
855 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
856 * @param resultSetConcurrency one of the following <code>ResultSet</code>
857 * constants:
858 * <code>ResultSet.CONCUR_READ_ONLY</code> or
859 * <code>ResultSet.CONCUR_UPDATABLE</code>
860 * @param resultSetHoldability one of the following <code>ResultSet</code>
861 * constants:
862 * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
863 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
864 * @return a new <code>PreparedStatement</code> object, containing the
865 * pre-compiled SQL statement, that will generate
866 * <code>ResultSet</code> objects with the given type,
867 * concurrency, and holdability
868 * @exception SQLException if a database access error occurs
869 * or the given parameters are not <code>ResultSet</code>
870 * constants indicating type, concurrency, and holdability
871 * @see java.sql.ResultSet
872 * @since 1.4
873 */
874 public PreparedStatement prepareStatement(String sql, int resultSetType,
875 int resultSetConcurrency, int resultSetHoldability) throws SQLException {
876 checkConnection();
877
878 final PreparedStatement statement = new PreparedStatementWrapper(
879 delegate_.prepareStatement( sql, resultSetType, resultSetConcurrency, resultSetHoldability ) );
880 openStatements_.add( statement );
881 return statement;
882 }
883
884
885 /***
886 * Creates a <code>CallableStatement</code> object that will generate
887 * <code>ResultSet</code> objects with the given type and concurrency.
888 * This method is the same as the <code>prepareCall</code> method
889 * above, but it allows the default result set
890 * type, result set concurrency type and holdability to be overridden.
891 *
892 * @param sql a <code>String</code> object that is the SQL statement to
893 * be sent to the database; may contain on or more ? parameters
894 * @param resultSetType one of the following <code>ResultSet</code>
895 * constants:
896 * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
897 * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
898 * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
899 * @param resultSetConcurrency one of the following <code>ResultSet</code>
900 * constants:
901 * <code>ResultSet.CONCUR_READ_ONLY</code> or
902 * <code>ResultSet.CONCUR_UPDATABLE</code>
903 * @param resultSetHoldability one of the following <code>ResultSet</code>
904 * constants:
905 * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
906 * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
907 * @return a new <code>CallableStatement</code> object, containing the
908 * pre-compiled SQL statement, that will generate
909 * <code>ResultSet</code> objects with the given type,
910 * concurrency, and holdability
911 * @exception SQLException if a database access error occurs
912 * or the given parameters are not <code>ResultSet</code>
913 * constants indicating type, concurrency, and holdability
914 * @see java.sql.ResultSet
915 * @since 1.4
916 */
917 public CallableStatement prepareCall(String sql, int resultSetType,
918 int resultSetConcurrency, int resultSetHoldability) throws SQLException {
919 checkConnection();
920
921 final CallableStatement statement = new CallableStatementWrapper(
922 delegate_.prepareCall( sql, resultSetType, resultSetConcurrency, resultSetHoldability) );
923 openStatements_.add( statement );
924 return statement;
925 }
926
927
928 /***
929 * Creates a default <code>PreparedStatement</code> object that has
930 * the capability to retrieve auto-generated keys. The given constant
931 * tells the driver whether it should make auto-generated keys
932 * available for retrieval. This parameter is ignored if the SQL
933 * statement is not an <code>INSERT</code> statement.
934 * <P>
935 * <B>Note:</B> This method is optimized for handling
936 * parametric SQL statements that benefit from precompilation. If
937 * the driver supports precompilation,
938 * the method <code>prepareStatement</code> will send
939 * the statement to the database for precompilation. Some drivers
940 * may not support precompilation. In this case, the statement may
941 * not be sent to the database until the <code>PreparedStatement</code>
942 * object is executed. This has no direct effect on users; however, it does
943 * affect which methods throw certain SQLExceptions.
944 * <P>
945 * Result sets created using the returned <code>PreparedStatement</code>
946 * object will by default be type <code>TYPE_FORWARD_ONLY</code>
947 * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
948 *
949 * @param sql an SQL statement that may contain one or more '?' IN
950 * parameter placeholders
951 * @param autoGeneratedKeys a flag indicating whether auto-generated keys
952 * should be returned; one of
953 * <code>Statement.RETURN_GENERATED_KEYS</code> or
954 * <code>Statement.NO_GENERATED_KEYS</code>
955 * @return a new <code>PreparedStatement</code> object, containing the
956 * pre-compiled SQL statement, that will have the capability of
957 * returning auto-generated keys
958 * @exception SQLException if a database access error occurs
959 * or the given parameter is not a <code>Statement</code>
960 * constant indicating whether auto-generated keys should be
961 * returned
962 * @since 1.4
963 */
964 public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
965 checkConnection();
966
967 final PreparedStatement statement
968 = new PreparedStatementWrapper( delegate_.prepareStatement( sql, autoGeneratedKeys ) );
969 openStatements_.add( statement );
970 return statement;
971 }
972
973
974 /***
975 * Creates a default <code>PreparedStatement</code> object capable
976 * of returning the auto-generated keys designated by the given array.
977 * This array contains the indexes of the columns in the target
978 * table that contain the auto-generated keys that should be made
979 * available. This array is ignored if the SQL
980 * statement is not an <code>INSERT</code> statement.
981 * <P>
982 * An SQL statement with or without IN parameters can be
983 * pre-compiled and stored in a <code>PreparedStatement</code> object. This
984 * object can then be used to efficiently execute this statement
985 * multiple times.
986 * <P>
987 * <B>Note:</B> This method is optimized for handling
988 * parametric SQL statements that benefit from precompilation. If
989 * the driver supports precompilation,
990 * the method <code>prepareStatement</code> will send
991 * the statement to the database for precompilation. Some drivers
992 * may not support precompilation. In this case, the statement may
993 * not be sent to the database until the <code>PreparedStatement</code>
994 * object is executed. This has no direct effect on users; however, it does
995 * affect which methods throw certain SQLExceptions.
996 * <P>
997 * Result sets created using the returned <code>PreparedStatement</code>
998 * object will by default be type <code>TYPE_FORWARD_ONLY</code>
999 * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
1000 *
1001 * @param sql an SQL statement that may contain one or more '?' IN
1002 * parameter placeholders
1003 * @param columnIndexes an array of column indexes indicating the columns
1004 * that should be returned from the inserted row or rows
1005 * @return a new <code>PreparedStatement</code> object, containing the
1006 * pre-compiled statement, that is capable of returning the
1007 * auto-generated keys designated by the given array of column
1008 * indexes
1009 * @exception SQLException if a database access error occurs
1010 *
1011 * @since 1.4
1012 */
1013 public PreparedStatement prepareStatement(String sql, int columnIndexes[]) throws SQLException {
1014 checkConnection();
1015
1016 final PreparedStatement statement
1017 = new PreparedStatementWrapper( delegate_.prepareStatement( sql, columnIndexes ) );
1018 openStatements_.add( statement );
1019 return statement;
1020 }
1021
1022
1023 /***
1024 * Creates a default <code>PreparedStatement</code> object capable
1025 * of returning the auto-generated keys designated by the given array.
1026 * This array contains the names of the columns in the target
1027 * table that contain the auto-generated keys that should be returned.
1028 * This array is ignored if the SQL
1029 * statement is not an <code>INSERT</code> statement.
1030 * <P>
1031 * An SQL statement with or without IN parameters can be
1032 * pre-compiled and stored in a <code>PreparedStatement</code> object. This
1033 * object can then be used to efficiently execute this statement
1034 * multiple times.
1035 * <P>
1036 * <B>Note:</B> This method is optimized for handling
1037 * parametric SQL statements that benefit from precompilation. If
1038 * the driver supports precompilation,
1039 * the method <code>prepareStatement</code> will send
1040 * the statement to the database for precompilation. Some drivers
1041 * may not support precompilation. In this case, the statement may
1042 * not be sent to the database until the <code>PreparedStatement</code>
1043 * object is executed. This has no direct effect on users; however, it does
1044 * affect which methods throw certain SQLExceptions.
1045 * <P>
1046 * Result sets created using the returned <code>PreparedStatement</code>
1047 * object will by default be type <code>TYPE_FORWARD_ONLY</code>
1048 * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
1049 *
1050 * @param sql an SQL statement that may contain one or more '?' IN
1051 * parameter placeholders
1052 * @param columnNames an array of column names indicating the columns
1053 * that should be returned from the inserted row or rows
1054 * @return a new <code>PreparedStatement</code> object, containing the
1055 * pre-compiled statement, that is capable of returning the
1056 * auto-generated keys designated by the given array of column
1057 * names
1058 * @exception SQLException if a database access error occurs
1059 *
1060 * @since 1.4
1061 */
1062 public PreparedStatement prepareStatement(String sql, String columnNames[]) throws SQLException {
1063 checkConnection();
1064
1065 final PreparedStatement statement
1066 = new PreparedStatementWrapper( delegate_.prepareStatement( sql, columnNames ) );
1067 openStatements_.add( statement );
1068 return statement;
1069 }
1070 }
1071