KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > jdbc > jdbcConnection


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb.jdbc;
33
34 import java.sql.CallableStatement JavaDoc;
35 import java.sql.Connection JavaDoc;
36 import java.sql.DatabaseMetaData JavaDoc;
37 import java.sql.PreparedStatement JavaDoc;
38 import java.sql.SQLException JavaDoc;
39 import java.sql.SQLWarning JavaDoc;
40 import java.sql.Statement JavaDoc;
41
42 //#ifdef JDBC3
43
import java.sql.Savepoint JavaDoc;
44
45 //#endif JDBC3
46
//#ifdef JAVA2
47
import java.util.Map JavaDoc;
48
49 //#endif JAVA2
50
import java.util.Locale JavaDoc;
51
52 import org.hsqldb.DatabaseManager;
53 import org.hsqldb.DatabaseURL;
54 import org.hsqldb.HSQLClientConnection;
55 import org.hsqldb.HTTPClientConnection;
56 import org.hsqldb.HsqlException;
57 import org.hsqldb.persist.HsqlProperties;
58 import org.hsqldb.Result;
59 import org.hsqldb.ResultConstants;
60 import org.hsqldb.Session;
61 import org.hsqldb.SessionInterface;
62 import org.hsqldb.Trace;
63 import org.hsqldb.lib.StringUtil;
64
65 // fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
66
// JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
67
// boucherb@users 20020509 - added "throws SQLException" to all methods where
68
// it was missing here but specified in the java.sql.Connection interface,
69
// updated generic documentation to JDK 1.4, and added JDBC3 methods and docs
70
// boucherb@users and fredt@users 20020505 - extensive review and update
71
// of docs and behaviour to comply with java.sql specification
72
// fredt@users 20020830 - patch 487323 by xclayl@users - better synchronization
73
// fredt@users 20020930 - patch 1.7.1 - support for connection properties
74
// kneedeepincode@users 20021110 - patch 635816 - correction to properties
75
// unsaved@users 20021113 - patch 1.7.2 - SSL support
76
// boucherb@users 2003 ??? - patch 1.7.2 - SSL support moved to factory interface
77
// fredt@users 20030620 - patch 1.7.2 - reworked to use a SessionInterface
78
// boucherb@users 20030801 - JavaDoc updates to reflect new connection urls
79
// boucherb@users 20030819 - patch 1.7.2 - partial fix for broken nativeSQL method
80
// boucherb@users 20030819 - patch 1.7.2 - SQLWarning cases implemented
81

82 /**
83  * <!-- start generic documentation -->
84  * A connection (session) with a specific database. Within the context
85  * of a Connection, SQL statements are executed and results
86  * are returned. <p>
87  *
88  * A Connection's database is able to provide information describing
89  * its tables, its supported SQL grammar, its stored procedures, the
90  * capabilities of this connection, and so on. This information is
91  * obtained with the <code>getMetaData</code> method. <p>
92  *
93  * <B>Note:</B> By default the Connection automatically commits
94  * changes after executing each statement. If auto commit has been
95  * disabled, an explicit commit must be done or database changes will
96  * not be saved. <p>
97  *
98  * <!-- end generic documentation -->
99  * <!-- start release-specific documentation -->
100  * <div class="ReleaseSpecificDocumentation">
101  *
102  * <hr>
103  *
104  * <b>HSQLDB-Specific Information:</b> <p>
105  *
106  * To get a <code>Connection</code> to an HSQLDB database, the
107  * following code may be used (updated to reflect the most recent
108  * recommendations): <p>
109  *
110  * <hr>
111  *
112  * When using HSQLDB, the database connection <b>&lt;url&gt;</b> must start with
113  * <b>'jdbc:hsqldb:'</b><p>
114  *
115  * Since 1.7.2, connection properties (&lt;key-value-pairs&gt;) may be appended
116  * to the database connection <b>&lt;url&gt;</b>, using the form: <p>
117  *
118  * <blockquote>
119  * <b>'&lt;url&gt;[;key=value]*'</b>
120  * </blockquote> <p>
121  *
122  * Also since 1.7.2, the allowable forms of the HSQLDB database connection
123  * <b>&lt;url&gt;</b> have been extended. However, all legacy forms continue
124  * to work, with unchanged semantics. The extensions are as described in the
125  * following material. <p>
126  *
127  * <hr>
128  *
129  * <b>Network Server Database Connections:</b> <p>
130  *
131  * The 1.7.2 {@link Server Server} database connection <b>&lt;url&gt;</b> has
132  * changed to take one of the two following forms: <p>
133  *
134  * <div class="GeneralExample">
135  * <ol>
136  * <li> <b>'jdbc:hsqldb:hsql://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
137  *
138  * <li> <b>'jdbc:hsqldb:hsqls://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
139  * (with TLS).
140  * </ol>
141  * </div> <p>
142  *
143  * The 1.7.2 {@link WebServer WebServer} database connection <b>&lt;url&gt;</b>
144  * also changes to take one of two following forms: <p>
145  *
146  * <div class="GeneralExample">
147  * <ol>
148  * <li> <b>'jdbc:hsqldb:http://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
149  *
150  * <li> <b>'jdbc:hsqldb:https://host[:port][/&lt;alias&gt;][&lt;key-value-pairs&gt;]'</b>
151  * (with TLS).
152  * </ol>
153  * </div><p>
154  *
155  * In both network server database connection <b>&lt;url&gt;</b> forms, the
156  * optional <b>&lt;alias&gt;</b> component is used to identify one of possibly
157  * several database instances available at the indicated host and port. If the
158  * <b>&lt;alias&gt;</b> component is omitted, then a connection is made to the
159  * network server's default database instance. <p>
160  *
161  * For more information on server configuration regarding mounting multiple
162  * databases and assigning them <b>&lt;alias&gt;</b> values, please read the
163  * Java API documentation for {@link org.hsqldb.Server Server} and related
164  * chapters in the general documentation, especially the Advanced Users
165  * Guide. <p>
166  *
167  * <hr>
168  *
169  * <b>Transient, In-Process Database Connections:</b> <p>
170  *
171  * The 1.7.2 100% in-memory (transient, in-process) database connection
172  * <b>&lt;url&gt;</b> takes one of the two following forms: <p>
173  *
174  * <div class="GeneralExample">
175  * <ol>
176  * <li> <b>'jdbc:hsqldb:.[&lt;key-value-pairs&gt;]'</b>
177  * (the legacy form, extended)
178  *
179  * <li> <b>'jdbc:hsqldb:mem:&lt;alias&gt;[&lt;key-value-pairs&gt;]'</b>
180  * (the new form)
181  * </ol>
182  * </div> <p>
183  *
184  * With the 1.7.2 transient, in-process database connection <b>&lt;url&gt;</b>,
185  * the <b>&lt;alias&gt;</b> component is the key used to look up a transient,
186  * in-process database instance amongst the collection of all such instances
187  * already in existence within the current class loading context in the
188  * current JVM. If no such instance exists, one <em>may</em> be automatically
189  * created and mapped to the <b>&lt;alias&gt;</b>, as governed by the
190  * <b>'ifexists=true|false'</b> connection property. <p>
191  *
192  * <hr>
193  *
194  * <b>Persistent, In-Process Database Connections:</b> <p>
195  *
196  * The 1.7.2 standalone (persistent, in-process) database connection
197  * <b>&lt;url&gt;</b> takes one of the three following forms: <p>
198  *
199  * <div class="GeneralExample">
200  * <ol>
201  * <li> <b>'jdbc:hsqldb:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
202  * (the legacy form, extended)
203  *
204  * <li> <b>'jdbc:hsqldb:file:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
205  * (same semantics as the legacy form)
206  *
207  * <li> <b>'jdbc:hsqldb:res:&lt;path&gt;[&lt;key-value-pairs&gt;]'</b>
208  * (new form with 'files_in_jar' semantics)
209  * </ol>
210  * </div> <p>
211  *
212  * For the persistent, in-process database connection <b>&lt;url&gt;</b>,
213  * the <b>&lt;path&gt;</b> component is the path prefix common to all of
214  * the files that compose the database. <p>
215  *
216  * As of 1.7.2, although other files may be involved (such as transient working
217  * files and/or TEXT table CSV data source files), the essential set that may,
218  * at any particular point in time, compose an HSQLDB database are: <p>
219  *
220  * <div class="GeneralExample">
221  * <ul>
222  * <li>&lt;path&gt;.properties
223  * <li>&lt;path&gt;.script
224  * <li>&lt;path&gt;.log
225  * <li>&lt;path&gt;.data
226  * <li>&lt;path&gt;.backup
227  * <li>&lt;path&gt;.lck
228  * </ul>
229  * </div> <p>
230  *
231  * For example: <b>'jdbc:hsqldb:file:test'</b> connects to a database
232  * composed of some subset of the files listed above, where the expansion
233  * of <b>&lt;path&gt;</b> is <b>'test'</b> prefixed with the path of the
234  * working directory fixed at the time the JVM is started. <p>
235  *
236  * Under <em>Windows</em> <sup><font size="-2">TM</font> </sup>, <b>
237  * 'jdbc:hsqldb:file:c:\databases\test'</b> connects to a database located
238  * on drive <b>'C:'</b> in the directory <b>'databases'</b>, composed
239  * of some subset of the files: <p>
240  *
241  * <pre class="GeneralExample">
242  * C:\
243  * +--databases\
244  * +--test.properties
245  * +--test.script
246  * +--test.log
247  * +--test.data
248  * +--test.backup
249  * +--test.lck
250  * </pre>
251  *
252  * Under most variations of UNIX, <b>'jdbc:hsqldb:file:/databases/test'</b>
253  * connects to a database located in the directory <b>'databases'</b> directly
254  * under root, once again composed of some subset of the files: <p>
255  *
256  * <pre class="GeneralExample">
257  * /
258  * +--databases/
259  * +--test.properties
260  * +--test.script
261  * +--test.log
262  * +--test.data
263  * +--test.backup
264  * +--test.lck
265  * </pre>
266  *
267  * <b>Some Guidelines:</b> <p>
268  *
269  * <ol>
270  * <li> Both relative and absolute database file paths are supported. <p>
271  *
272  * <li> Relative database file paths can be specified in a platform independent
273  * manner as: <b>'[dir1/dir2/.../dirn/]&lt;file-name-prefix&gt;'</b>. <p>
274  *
275  * <li> Specification of absolute file paths is operating-system specific.<br>
276  * Please read your OS file system documentation. <p>
277  *
278  * <li> Specification of network mounts may be operating-system specific.<br>
279  * Please read your OS file system documentation. <p>
280  *
281  * <li> Special care may be needed w.r.t. file path specifications
282  * containing whitespace, mixed-case, special characters and/or
283  * reserved file names.<br>
284  * Please read your OS file system documentation. <p>
285  * </ol> <p>
286  *
287  * <b>Note:</b> Versions of HSQLDB previous to 1.7.0 did not support creating
288  * directories along the file path specified in the persistent, in-process mode
289  * database connection <b>&lt;url&gt;</b> form, in the case that they did
290  * not already exist. Starting with HSQLDB 1.7.0, directories <i>will</i>
291  * be created if they do not already exist., but only if HSQLDB is built under
292  * a version of the compiler greater than JDK 1.1.x. <p>
293  *
294  * <b>res: Connections</b><p>
295  *
296  * The new <b>'jdbc:hsqldb:res:&lt;path&gt;'</b> database connection
297  * <b>&lt;url&gt;</b> has different semantics than the
298  * <b>'jdbc:hsqldb:file:&lt;path&gt;'</b> form. The semantics are similar to
299  * those of a <b>'files_readonly'</b> database, but with some additional
300  * points to consider. <p>
301  *
302  * Specifically, the <b>'&lt;path&gt;'</b> component of a <b>res:</b> type
303  * database connection <b>&lt;url&gt;</b> is used to obtain resource URL
304  * objects and thereby read the database files as resources on the class path.
305  * Moreover, the URL objects <i>must</i> point only to resources contained
306  * in one or more jars on the class path (must be jar protocol). <p>
307  *
308  * This restriction is enforced to avoid the unfortunate situation in which,
309  * because <b>res:</b> database instances do not create a &lt;path&gt;.lck file
310  * (they are strictly files-read-only) and because the <b>&lt;path&gt;</b>
311  * components of <b>res:</b> and <b>file:</b> database URIs are not checked
312  * for file system equivalence, it is possible for the same database files to
313  * be accessed concurrently by both <b>file:</b> and <b>res:</b> database
314  * instances. That is, without this restriction, it is possible that
315  * &lt;path&gt;.data and &lt;path&gt;.properties file content may be written
316  * by a <b>file:</b> database instance without the knowlege or cooperation
317  * of a <b>res:</b> database instance open on the same files, potentially
318  * resulting in unexpected database errors, inconsistent operation
319  * and/or data corruption. <p>
320  *
321  * In short, a <b>res:</b> type database connection <b>&lt;url&gt;</b> is
322  * designed specifically to connect to a <b>'files_in_jar'</b> mode database
323  * instance, which in turn is designed specifically to operate under
324  * <em>Java WebStart</em><sup><font size="-2">TM</font></sup> and
325  * <em>Java Applet</em><sup><font size="-2">TM</font></sup>configurations,
326  * where co-locating the database files in the jars that make up the
327  * <em>WebStart</em> application or Applet avoids the need for special security
328  * configuration or code signing. <p>
329  *
330  * <b>Note:</b> Since it is difficult and often nearly impossible to determine
331  * or control at runtime from where all classes are being loaded or which class
332  * loader is doing the loading under <b>'files_in_jar'</b> semantics, the
333  * <b>&lt;path&gt;</b> component of the res: database connection
334  * <b>&lt;url&gt;</b> is always taken to be relative to the default package.
335  * That is, if the <b>&lt;path&gt;</b> component does not start with '/', then
336  * '/' is prepended when obtaining the resource URLs used to read the database
337  * files. <p>
338  *
339  * <hr>
340  *
341  * For more information about HSQLDB file structure, various database modes
342  * and other attributes such as those controlled through the HSQLDB properties
343  * files, please read the general documentation, especially the Advanced Users
344  * Guide. <p>
345  *
346  * <hr>
347  *
348  * <b>JRE 1.1.x Notes:</b> <p>
349  *
350  * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
351  * Java 1.4 and above. In HSQLDB, support for methods introduced in different
352  * versions of JDBC depends on the JDK version used for compiling and building
353  * HSQLDB.<p>
354  *
355  * Since 1.7.0, it is possible to build the product so that
356  * all JDBC 2 methods can be called while executing under the version 1.1.x
357  * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
358  * However, in addition to this technique requiring explicit casts to the
359  * org.hsqldb.jdbcXXX classes, some of the method calls also require
360  * <code>int</code> values that are defined only in the JDBC 2 or greater
361  * version of
362  * <a HREF="http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSet.html">
363  * <code>ResultSet</code></a> interface. For this reason, when the
364  * product is compiled under JDK 1.1.x, these values are defined
365  * in {@link org.hsqldb.jdbc.jdbcResultSet jdbcResultSet}. <p>
366  *
367  * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
368  * JDBC2-only <code>ResultSet</code> values can be achieved by referring
369  * to them in parameter specifications and return value comparisons,
370  * respectively, as follows: <p>
371  *
372  * <pre class="JavaCodeExample">
373  * jdbcResultSet.FETCH_FORWARD
374  * jdbcResultSet.TYPE_FORWARD_ONLY
375  * jdbcResultSet.TYPE_SCROLL_INSENSITIVE
376  * jdbcResultSet.CONCUR_READ_ONLY
377  * // etc.
378  * </pre>
379  *
380  * However, please note that code written to use HSQLDB JDBC 2 features under
381  * JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
382  * also note that this feature is offered solely as a convenience to developers
383  * who must work under JDK 1.1.x due to operating constraints, yet wish to
384  * use some of the more advanced features available under the JDBC 2
385  * specification. <p>
386  *
387  * <hr>
388  *
389  * (fredt@users)<br>
390  * (boucherb@users)<p>
391  *
392  * </div> <!-- end release-specific documentation -->
393  * @author boucherb@users
394  * @author fredt@users
395  * @version 1.7.2
396  * @see org.hsqldb.jdbcDriver
397  * @see jdbcStatement
398  * @see jdbcPreparedStatement
399  * @see jdbcCallableStatement
400  * @see jdbcResultSet
401  * @see jdbcDatabaseMetaData
402  */

403 public class jdbcConnection implements Connection JavaDoc {
404
405 // ---------------------------- Common Attributes --------------------------
406

407     /**
408      * Properties for the connection
409      *
410      */

411     HsqlProperties connProperties;
412
413     /**
414      * This connection's interface to the corresponding Session
415      * object in the database engine.
416      */

417     SessionInterface sessionProxy;
418
419     /**
420      * Is this an internal connection?
421      */

422     boolean isInternal;
423
424     /** Is this connection to a network server instance. */
425     protected boolean isNetConn;
426
427     /**
428      * Is this connection closed?
429      */

430     boolean isClosed;
431
432     /** The first warning in the chain. Null if there are no warnings. */
433     private SQLWarning JavaDoc rootWarning;
434
435     /** Synchronizes concurrent modification of the warning chain */
436     private Object JavaDoc rootWarning_mutex = new Object JavaDoc();
437
438     /**
439      * The set of open Statement objects returned by this Connection from
440      * calls to createStatement, prepareCall and prepareStatement. This is
441      * used solely for closing the statements when this Connection is closed.
442      */

443     /*
444     private org.hsqldb.lib.HashSet statementSet =
445         new org.hsqldb.lib.HashSet();
446      */

447
448 // ----------------------------------- JDBC 1 -------------------------------
449

450     /**
451      * <!-- start generic documentation -->
452      * Creates a <code>Statement</code>
453      * object for sending SQL statements to the database. SQL
454      * statements without parameters are normally executed using
455      * <code>Statement</code> objects. If the same SQL statement is
456      * executed many times, it may be more efficient to use a
457      * <code>PreparedStatement</code> object.<p>
458      *
459      * Result sets created using the returned <code>Statement</code>
460      * object will by default be type <code>TYPE_FORWARD_ONLY</code>
461      * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.<p>
462      *
463      * <!-- end generic documentation -->
464      * <!-- start release-specific documentation -->
465      * <div class="ReleaseSpecificDocumentation">
466      * <h3>HSQLDB-Specific Information:</h3> <p>
467      *
468      * Starting with HSQLDB 1.7.2, support for precompilation at the engine level
469      * has been implemented, so it is now much more efficient and performant
470      * to use a <code>PreparedStatement</code> object if the same SQL statement
471      * is executed many times. <p>
472      *
473      * Up to 1.6.1, HSQLDB supported <code>TYPE_FORWARD_ONLY</code> -
474      * <code>CONCUR_READ_ONLY</code> results only, so <code>ResultSet</code>
475      * objects created using the returned <code>Statement</code>
476      * object would <I>always</I> be type <code>TYPE_FORWARD_ONLY</code>
477      * with <code>CONCUR_READ_ONLY</code> concurrency. <p>
478      *
479      * Starting with 1.7.0, HSQLDB also supports
480      * <code>TYPE_SCROLL_INSENSITIVE</code> results. <p>
481      *
482      * <b>Notes:</b> <p>
483      *
484      * Up to 1.6.1, calling this method returned <code>null</code> if the
485      * connection was already closed. This was possibly counter-intuitive
486      * to the expectation that an exception would be thrown for
487      * closed connections. Starting with 1.7.0. the behaviour is to throw a
488      * <code>SQLException</code> if the connection is closed. <p>
489      *
490      * </div> <!-- end release-specific documentation -->
491      *
492      * @return a new default Statement object
493      * @throws SQLException if a database access error occurs<p>
494      * @see #createStatement(int,int)
495      * @see #createStatement(int,int,int)
496      */

497     public synchronized Statement JavaDoc createStatement() throws SQLException JavaDoc {
498
499         checkClosed();
500
501         Statement JavaDoc stmt = new jdbcStatement(this,
502                                            jdbcResultSet.TYPE_FORWARD_ONLY);
503
504         return stmt;
505     }
506
507     /**
508      * <!-- start generic documentation -->
509      * Creates a <code>PreparedStatement</code>
510      * object for sending parameterized SQL statements to the
511      * database. <p>
512      *
513      * A SQL statement with or without IN parameters can be
514      * pre-compiled and stored in a <code>PreparedStatement</code>
515      * object. This object can then be used to efficiently execute
516      * this statement multiple times. <p>
517      *
518      * <B>Note:</B> This method is optimized for handling parametric
519      * SQL statements that benefit from precompilation. If the driver
520      * supports precompilation, the method <code>prepareStatement</code>
521      * will send the statement to the database for precompilation.
522      * Some drivers may not support precompilation. In this case, the
523      * statement may not be sent to the database until the
524      * <code>PreparedStatement</code> object is executed. This has no
525      * direct effect on users; however, it does affect which methods
526      * throw certain <code>SQLException</code> objects.<p>
527      *
528      * Result sets created using the returned <code>PreparedStatement</code>
529      * object will by default be type <code>TYPE_FORWARD_ONLY</code>
530      * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.<p>
531      *
532      * <!-- end generic documentation -->
533      * <!-- start release-specific documentation -->
534      * <div class="ReleaseSpecificDocumentation">
535      * <h3>HSQLDB-Specific Information:</h3> <p>
536      *
537      * Starting with HSQLDB 1.7.2, support for precompilation at the engine level
538      * has been implemented, so it is now much more efficient and performant
539      * to use a <code>PreparedStatement</code> object if the same SQL statement
540      * is executed many times. <p>
541      *
542      * Starting with 1.7.2, the support for and behaviour of
543      * PreparedStatment has changed. Please read the introductory section
544      * of the documentation for org.hsqldb.jdbc.jdbcPreparedStatement. <P>
545      *
546      * </div> <!-- end release-specific documentation -->
547      *
548      * @param sql an SQL statement that may contain one or more '?'
549      * IN parameter placeholders
550      * @return a new default <code>PreparedStatement</code> object
551      * containing the pre-compiled SQL statement
552      * @exception SQLException if a database access error occurs <p>
553      * @see #prepareStatement(String,int,int)
554      */

555     public synchronized PreparedStatement JavaDoc prepareStatement(String JavaDoc sql)
556     throws SQLException JavaDoc {
557
558         PreparedStatement JavaDoc stmt;
559
560         checkClosed();
561
562         try {
563             stmt = new jdbcPreparedStatement(this, sql,
564                                              jdbcResultSet.TYPE_FORWARD_ONLY);
565
566             return stmt;
567         } catch (HsqlException e) {
568             throw Util.sqlException(e);
569         }
570     }
571
572     /**
573      * <!-- start generic documentation -->
574      * Creates a <code>CallableStatement</code>
575      * object for calling database stored procedures. The
576      * <code>CallableStatement</code> object provides methods for setting up
577      * its IN and OUT parameters, and methods for executing the call to a
578      * stored procedure. <p>
579      *
580      * <b>Note:</b> This method is optimized for handling stored
581      * procedure call statements. Some drivers may send the call
582      * statement to the database when the method <code>prepareCall</code>
583      * is done; others may wait until the <code>CallableStatement</code>
584      * object is executed. This has no direct effect on users;
585      * however, it does affect which method throws certain
586      * SQLExceptions. <p>
587      *
588      * Result sets created using the returned <code>CallableStatement</code>
589      * object will by default be type <code>TYPE_FORWARD_ONLY</code>
590      * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.<p>
591      *
592      * <!-- end generic documentation -->
593      * <!-- start release-specific documentation -->
594      * <div class="ReleaseSpecificDocumentation">
595      * <h3>HSQLDB-Specific Information:</h3> <p>
596      *
597      * Starting with 1.7.2, the support for and behaviour of
598      * CallableStatement has changed. Please read the introductory section
599      * of the documentation for org.hsqldb.jdbc.jdbcCallableStatement.
600      *
601      * </div> <!-- end release-specific documentation -->
602      *
603      * @param sql a String object that is the SQL statement to be
604      * sent to the database; may contain one or more ?
605      * parameters. <p>
606      *
607      * <B>Note:</B> Typically the SQL statement is a JDBC
608      * function call escape string.
609      * @return a new default <code>CallableStatement</code> object
610      * containing the pre-compiled SQL statement
611      * @exception SQLException if a database access error occurs <p>
612      * @see #prepareCall(String,int,int)
613      */

614     public synchronized CallableStatement JavaDoc prepareCall(String JavaDoc sql)
615     throws SQLException JavaDoc {
616
617         CallableStatement JavaDoc stmt;
618
619         checkClosed();
620
621         try {
622             stmt = new jdbcCallableStatement(this, sql,
623                                              jdbcResultSet.TYPE_FORWARD_ONLY);
624
625             return stmt;
626         } catch (HsqlException e) {
627             throw Util.sqlException(e);
628         }
629     }
630
631     /**
632      * <!-- start generic documentation -->
633      * Converts the given SQL statement
634      * into the system's native SQL grammar. A driver may convert the
635      * JDBC SQL grammar into its system's native SQL grammar prior to
636      * sending it. This method returns the native form of the
637      * statement that the driver would have sent. <p>
638      *
639      * <!-- end generic documentation -->
640      * <!-- start release-specific documentation -->
641      * <div class="ReleaseSpecificDocumentation">
642      * <h3>HSQLDB-Specific Information:</h3> <p>
643      *
644      * Up to and including 1.7.2, HSQLDB converts the JDBC SQL
645      * grammar into the system's native SQL grammar prior to sending
646      * it, if escape processing is set true; this method returns the
647      * native form of the statement that the driver would send in place
648      * of client-specified JDBC SQL grammar. <p>
649      *
650      * Before 1.7.2, escape processing was incomplete and
651      * also broken in terms of support for nested escapes. <p>
652      *
653      * Starting with 1.7.2, escape processing is complete and handles nesting
654      * to arbitrary depth, but enforces a very strict interpretation of the
655      * syntax and does not detect or process SQL comments. <p>
656      *
657      * In essence, the HSQLDB engine directly handles the prescribed syntax
658      * and date / time formats specified internal to the JDBC escapes.
659      * It also directly offers the XOpen / ODBC extended scalar
660      * functions specified available internal to the {fn ...} JDBC escape.
661      * As such, the driver simply removes the curly braces and JDBC escape
662      * codes in the simplest and fastest fashion possible, by replacing them
663      * with whitespace.
664      *
665      * But to avoid a great deal of complexity, certain forms of input
666      * whitespace are currently not recognised. For instance,
667      * the driver handles "{?= call ...}" but not "{ ?= call ...} or
668      * "{? = call ...}" <p>
669      *
670      * Also, comments embedded in SQL are currently not detected or
671      * processed and thus may have unexpected effects on the output
672      * of this method, for instance causing otherwise valid SQL to become
673      * invalid. It is especially important to be aware of this because escape
674      * processing is set true by default for Statement objects and is always
675      * set true when producing a PreparedStatement from prepareStatement()
676      * or CallableStatement from prepareCall(). Currently, it is simply
677      * recommended to avoid submitting SQL having comments containing JDBC
678      * escape sequence patterns and/or single or double quotation marks,
679      * as this will avoid any potential problems.
680      *
681      * It is intended to implement a less strict handling of whitespace and
682      * proper processing of SQL comments at some point in the near future,
683      * perhaps before the final 1.7.2 release.
684      *
685      * In any event, 1.7.2 now correctly processes the following JDBC escape
686      * forms to arbitrary nesting depth, but only if the exact whitespace
687      * layout described below is used: <p>
688      *
689      * <ol>
690      * <li>{call ...}
691      * <li>{?= call ...}
692      * <li>{fn ...}
693      * <li>{oj ...}
694      * <li>{d ...}
695      * <li>{t ...}
696      * <li>{ts ...}
697      * </ol> <p>
698      *
699      * </div> <!-- end release-specific documentation -->
700      *
701      * @param sql a SQL statement that may contain one or more '?'
702      * parameter placeholders
703      * @return the native form of this statement
704      * @throws SQLException if a database access error occurs <p>
705      */

706     public synchronized String JavaDoc nativeSQL(final String JavaDoc sql)
707     throws SQLException JavaDoc {
708
709         // boucherb@users 20030405
710
// FIXME: does not work properly for nested escapes
711
// e.g. {call ...(...,{ts '...'},....)} does not work
712
// boucherb@users 20030817
713
// TESTME: First kick at the FIXME cat done. Now lots of testing
714
// and refinment
715
checkClosed();
716
717         // CHECKME: Thow or return null if input is null?
718
if (sql == null || sql.length() == 0 || sql.indexOf('{') == -1) {
719             return sql;
720         }
721
722         // boolean changed = false;
723
int state = 0;
724         int len = sql.length();
725         int nest = 0;
726         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(sql.length()); //avoid 16 extra
727
String JavaDoc msg;
728
729         //--
730
final int outside_all = 0;
731         final int outside_escape_inside_single_quotes = 1;
732         final int outside_escape_inside_double_quotes = 2;
733
734         //--
735
final int inside_escape = 3;
736         final int inside_escape_inside_single_quotes = 4;
737         final int inside_escape_inside_double_quotes = 5;
738
739         // TODO:
740
// final int inside_single_line_comment = 6;
741
// final int inside_multi_line_comment = 7;
742
// Better than old way for large inputs and for avoiding GC overhead;
743
// toString() reuses internal char[], reducing memory requirment
744
// and garbage items 3:2
745
sb.append(sql);
746
747         for (int i = 0; i < len; i++) {
748             char c = sb.charAt(i);
749
750             switch (state) {
751
752                 case outside_all : // Not inside an escape or quotes
753
if (c == '\'') {
754                         state = outside_escape_inside_single_quotes;
755                     } else if (c == '"') {
756                         state = outside_escape_inside_double_quotes;
757                     } else if (c == '{') {
758                         i = onStartEscapeSequence(sql, sb, i);
759
760                         // changed = true;
761
nest++;
762
763                         state = inside_escape;
764                     }
765                     break;
766
767                 case outside_escape_inside_single_quotes : // inside ' ' only
768
case inside_escape_inside_single_quotes : // inside { } and ' '
769
if (c == '\'') {
770                         state -= 1;
771                     }
772                     break;
773
774                 case outside_escape_inside_double_quotes : // inside " " only
775
case inside_escape_inside_double_quotes : // inside { } and " "
776
if (c == '"') {
777                         state -= 2;
778                     }
779                     break;
780
781                 case inside_escape : // inside { }
782
if (c == '\'') {
783                         state = inside_escape_inside_single_quotes;
784                     } else if (c == '"') {
785                         state = inside_escape_inside_double_quotes;
786                     } else if (c == '}') {
787                         sb.setCharAt(i, ' ');
788
789                         // changed = true;
790
nest--;
791
792                         state = (nest == 0) ? outside_all
793                                             : inside_escape;
794                     } else if (c == '{') {
795                         i = onStartEscapeSequence(sql, sb, i);
796
797                         // changed = true;
798
nest++;
799
800                         state = inside_escape;
801                     }
802             }
803         }
804
805         return sb.toString();
806     }
807
808     /**
809      * <!-- start generic documentation -->
810      * Sets this connection's auto-commit mode to the given state.
811      * If a connection is in auto-commit mode, then all its SQL
812      * statements will be executed and committed as individual transactions.
813      * Otherwise, its SQL statements are grouped into transactions that
814      * are terminated by a call to either the method <code>commit</code> or
815      * the method <code>rollback</code>. By default, new connections are
816      * in auto-commit mode. <p>
817      *
818      * The commit occurs when the statement completes or the next
819      * execute occurs, whichever comes first. In the case of
820      * statements returning a <code>ResultSet</code> object, the
821      * statement completes when the last row of the <code>ResultSet</code>
822      * object has been retrieved or the <code>ResultSet</code> object
823      * has been closed. In advanced cases, a single statement may
824      * return multiple results as well as output parameter values. In
825      * these cases, the commit occurs when all results and output
826      * parameter values have been retrieved. <p>
827      *
828      * <B>NOTE:</B> If this method is called during a transaction,
829      * the transaction is committed. <p>
830      *
831      * <!-- end generic documentation -->
832      * <!-- start release-specific documentation -->
833      * <div class="ReleaseSpecificDocumentation">
834      * <h3>HSQLDB-Specific Information:</h3> <p>
835      *
836      * Up to and including HSQLDB 1.7.2, <p>
837      *
838      * <ol>
839      * <li> All rows of a result set are retrieved internally <em>
840      * before</em> the first row can actually be fetched.<br>
841      * Therefore, a statement can be considered complete as soon as
842      * any XXXStatement.executeXXX method returns. </li>
843      *
844      * <li> Multiple result sets and output parameters are not yet
845      * supported. </li>
846      * </ol>
847      * <p>
848      *
849      * (boucherb@users) </div> <!-- end release-specific
850      * documentation -->
851      *
852      * @param autoCommit <code>true</code> to enable auto-commit
853      * mode; <code>false</code> to disable it
854      * @exception SQLException if a database access error occurs
855      * @see #getAutoCommit
856      */

857     public synchronized void setAutoCommit(boolean autoCommit)
858     throws SQLException JavaDoc {
859
860         checkClosed();
861
862         try {
863             sessionProxy.setAutoCommit(autoCommit);
864         } catch (HsqlException e) {
865             throw Util.sqlException(e);
866         }
867     }
868
869     /**
870      * Gets the current auto-commit state.
871      *
872      * @return the current state of auto-commit mode
873      * @exception SQLException Description of the Exception
874      * @see #setAutoCommit
875      */

876     public synchronized boolean getAutoCommit() throws SQLException JavaDoc {
877
878         checkClosed();
879
880         try {
881             return sessionProxy.isAutoCommit();
882         } catch (HsqlException e) {
883             throw Util.sqlException(e);
884         }
885     }
886
887     /**
888      * <!-- start generic documentation -->
889      * Makes all changes made since the
890      * previous commit/rollback permanent and releases any database
891      * locks currently held by the Connection. This method should be
892      * used only when auto-commit mode has been disabled. <p>
893      *
894      * <!-- end generic documentation -->
895      * <!-- start release-specific documentation -->
896      * <div class="ReleaseSpecificDocumentation">
897      * <h3>HSQLDB-Specific Information:</h3> <p>
898      *
899      * Starting with HSQLDB 1.7.2, savepoints are supported both
900      * in SQL and via the JDBC interface. <p>
901      *
902      * Using SQL, savepoints may be set, released and used in rollback
903      * as follows:
904      *
905      * <pre>
906      * SAVEPOINT &lt;savepoint-name&gt;
907      * RELEASE SAVEPOINT &lt;savepoint-name&gt;
908      * ROLLBACK TO SAVEPOINT &lt;savepoint-name&gt;
909      * </pre>
910      *
911      * </div><!-- end release-specific documentation -->
912      *
913      * @exception SQLException if a database access error occurs
914      * @see #setAutoCommit
915      */

916     public synchronized void commit() throws SQLException JavaDoc {
917
918         checkClosed();
919
920         try {
921             sessionProxy.commit();
922         } catch (HsqlException e) {
923             throw Util.sqlException(e);
924         }
925     }
926
927     /**
928      * <!-- start generic documentation -->
929      * Drops all changes made since the
930      * previous commit/rollback and releases any database locks
931      * currently held by this Connection. This method should be used
932      * only when auto- commit has been disabled. <p>
933      *
934      * <!-- end generic documentation -->
935      * <!-- start release-specific documentation -->
936      * <div class="ReleaseSpecificDocumentation">
937      * <h3>HSQLDB-Specific Information:</h3> <p>
938      *
939      * Starting with HSQLDB 1.7.2, savepoints are fully supported both
940      * in SQL and via the JDBC interface. <p>
941      *
942      * Using SQL, savepoints may be set, released and used in rollback
943      * as follows:
944      *
945      * <pre>
946      * SAVEPOINT &lt;savepoint-name&gt;
947      * RELEASE SAVEPOINT &lt;savepoint-name&gt;
948      * ROLLBACK TO SAVEPOINT &lt;savepoint-name&gt;
949      * </pre>
950      *
951      * </div> <!-- end release-specific documentation -->
952      *
953      * @exception SQLException if a database access error occurs
954      * @see #setAutoCommit
955      */

956     public synchronized void rollback() throws SQLException JavaDoc {
957
958         checkClosed();
959
960         try {
961             sessionProxy.rollback();
962         } catch (HsqlException e) {
963             throw Util.sqlException(e);
964         }
965     }
966
967     /**
968      * <!-- start generic documentation -->
969      * Releases this <code>Connection</code>
970      * object's database and JDBC resources immediately instead of
971      * waiting for them to be automatically released.<p>
972      *
973      * Calling the method <code>close</code> on a <code>Connection</code>
974      * object that is already closed is a no-op. <p>
975      *
976      * <B>Note:</B> A <code>Connection</code> object is automatically
977      * closed when it is garbage collected. Certain fatal errors also
978      * close a <code>Connection</code> object. <p>
979      *
980      * <!-- end generic documentation -->
981      * <!-- start release-specific documentation -->
982      * <div class="ReleaseSpecificDocumentation">
983      * <h3>HSQLDB-Specific Information:</h3> <p>
984      *
985      * In 1.7.2, <code>INTERNAL</code> <code>Connection</code>
986      * objects are not closable from JDBC client code. <p>
987      *
988      * </div> <!-- end release-specific documentation -->
989      *
990      * @exception SQLException if a database access error occurs
991      */

992     public synchronized void close() throws SQLException JavaDoc {
993
994         // Changed to synchronized above because
995
// we would not want a sessionProxy.close()
996
// operation to occur concurrently with a
997
// statementXXX.executeXXX operation.
998
if (isInternal || isClosed) {
999             return;
1000        }
1001
1002        isClosed = true;
1003
1004        if (sessionProxy != null) {
1005            sessionProxy.close();
1006        }
1007
1008        sessionProxy = null;
1009        rootWarning = null;
1010        connProperties = null;
1011    }
1012
1013    /**
1014     * Tests to see if a Connection is closed.
1015     *
1016     * @return true if the connection is closed; false if it's still
1017     * open
1018     */

1019    public synchronized boolean isClosed() {
1020        return isClosed;
1021    }
1022
1023    /**
1024     * <!-- start generic documentation -->
1025     * Gets the metadata regarding this connection's database.
1026     * A Connection's database is able to provide information describing
1027     * its tables, its supported SQL grammar, its stored procedures,
1028     * the capabilities of this connection, and so on. This information
1029     * is made available through a <code>DatabaseMetaData</code> object. <p>
1030     *
1031     * <!-- end generic documentation -->
1032     * <!-- start release-specific documentation -->
1033     * <div class="ReleaseSpecificDocumentation">
1034     * <h3>HSQLDB-Specific Information:</h3> <p>
1035     *
1036     * JDBC <code>DatabaseMetaData</code> methods returning
1037     * <code>ResultSet</code> were not implemented fully before 1.7.2.
1038     * Some of these methods always returned empty result sets.
1039     * Other methods did not accurately
1040     * reflect all of the MetaData for the category.
1041     * Also, some method ignored the filters provided as
1042     * parameters, returning an unfiltered result each time. <p>
1043     *
1044     * Also, the majority of methods returning <code>ResultSet</code>
1045     * threw an <code>SQLException</code> when accessed by a non-admin
1046     * user.
1047     * <hr>
1048     *
1049     * Starting with HSQLDB 1.7.2, essentially full database metadata
1050     * is supported. <p>
1051     *
1052     * For discussion in greater detail, please follow the link to the
1053     * overview for jdbcDatabaseMetaData, below.
1054     *
1055     * </div> <!-- end release-specific documentation -->
1056     *
1057     * @return a DatabaseMetaData object for this Connection
1058     * @throws SQLException if a database access error occurs
1059     * @see jdbcDatabaseMetaData
1060     */

1061    public synchronized DatabaseMetaData JavaDoc getMetaData() throws SQLException JavaDoc {
1062
1063        checkClosed();
1064
1065        return new jdbcDatabaseMetaData(this);
1066    }
1067
1068    /**
1069     * <!-- start generic documentation -->
1070     * Puts this connection in read-only mode as a hint to enable
1071     * database optimizations. <p>
1072     *
1073     * <B>Note:</B> This method should not be called while in the
1074     * middle of a transaction. <p>
1075     *
1076     * <!-- end generic documentation -->
1077     * <!-- start release-specific documentation -->
1078     * <div class="ReleaseSpecificDocumentation">
1079     * <h3>HSQLDB-Specific Information:</h3> <p>
1080     *
1081     * Up to and including 1.7.2, HSQLDB will commit the current
1082     * transaction automatically when this method is called. <p>
1083     *
1084     * Additionally, HSQLDB provides a way to put a whole database in
1085     * read-only mode. This is done by manually adding the line
1086     * 'readonly=true' to the database's .properties file while the
1087     * database is offline. Upon restart, all connections will be
1088     * readonly, since the entire database will be readonly. To take
1089     * a database out of readonly mode, simply take the database
1090     * offline and remove the line 'readonly=true' from the
1091     * database's .properties file. Upon restart, the database will
1092     * be in regular (read-write) mode. <p>
1093     *
1094     * When a database is put in readonly mode, its files are opened
1095     * in readonly mode, making it possible to create CD-based
1096     * readonly databases. To create a CD-based readonly database
1097     * that has CACHED tables and whose .data file is suspected of
1098     * being highly fragmented, it is recommended that the database
1099     * first be SHUTDOWN COMPACTed before copying the database
1100     * files to CD. This will reduce the space required and may
1101     * improve access times against the .data file which holds the
1102     * CACHED table data. <p>
1103     *
1104     * Starting with 1.7.2, an alternate approach to opimizing the
1105     * .data file before creating a CD-based readonly database is to issue
1106     * the CHECKPOINT DEFRAG command followed by SHUTDOWN to take the
1107     * database offline in preparation to burn the database files to CD. <p>
1108     *
1109     * </div> <!-- end release-specific documentation -->
1110     *
1111     * @param readonly The new readOnly value
1112     * @exception SQLException if a database access error occurs
1113     */

1114    public synchronized void setReadOnly(boolean readonly)
1115    throws SQLException JavaDoc {
1116
1117        checkClosed();
1118
1119        try {
1120            sessionProxy.setReadOnly(readonly);
1121        } catch (HsqlException e) {
1122            throw Util.sqlException(e);
1123        }
1124    }
1125
1126    /**
1127     * Tests to see if the connection is in read-only mode.
1128     *
1129     * @return true if connection is read-only and false otherwise
1130     * @exception SQLException if a database access error occurs
1131     */

1132    public synchronized boolean isReadOnly() throws SQLException JavaDoc {
1133
1134        try {
1135            return sessionProxy.isReadOnly();
1136        } catch (HsqlException e) {
1137            throw Util.sqlException(e);
1138        }
1139    }
1140
1141    /**
1142     * <!-- start generic documentation -->
1143     * Sets a catalog name in order to
1144     * select a subspace of this Connection's database in which to
1145     * work. <p>
1146     *
1147     * <!-- end generic documentation -->
1148     * <!-- start release-specific documentation -->
1149     * <div class="ReleaseSpecificDocumentation">
1150     * <h3>HSQLDB-Specific Information:</h3> <p>
1151     *
1152     * HSQLDB does not yet support catalogs and simply ignores this
1153     * request. <p>
1154     * </div>
1155     * <!-- end release-specific documentation -->
1156     *
1157     * @param catalog the name of a catalog (subspace in this
1158     * Connection object's database) in which to work (Ignored)
1159     * @throws SQLException if a database access error occurs <p>
1160     */

1161    public synchronized void setCatalog(String JavaDoc catalog) throws SQLException JavaDoc {
1162        checkClosed();
1163    }
1164
1165    /**
1166     * <!-- start generic documentation -->
1167     * Returns the Connection's current catalog name. <p>
1168     *
1169     * <!-- end generic documentation -->
1170     * <!-- start release-specific documentation -->
1171     * <div class="ReleaseSpecificDocumentation">
1172     * <h3>HSQLDB-Specific Information:</h3> <p>
1173     *
1174     * HSQLDB does not yet support catalogs and always returns null.
1175     * <p>
1176     *
1177     * </div> <!-- end release-specific documentation -->
1178     *
1179     * @return the current catalog name or null <p>
1180     *
1181     * For HSQLDB, this is always null.
1182     * @exception SQLException Description of the Exception
1183     */

1184    public synchronized String JavaDoc getCatalog() throws SQLException JavaDoc {
1185
1186        checkClosed();
1187
1188        return null;
1189    }
1190
1191    /**
1192     * <!-- start generic documentation -->
1193     * Attempts to change the transaction isolation level for this
1194     * <code>Connection</code> object to the one given. The constants
1195     * defined in the interface <code>Connection</code> are the
1196     * possible transaction isolation levels. <p>
1197     *
1198     * <B>Note:</B> If this method is called during a transaction,
1199     * the result is implementation-defined. <p>
1200     *
1201     * <!-- end generic documentation -->
1202     * <!-- start release-specific documentation -->
1203     * <div class="ReleaseSpecificDocumentation">
1204     * </div> <!-- end release-specific documentation -->
1205     *
1206     * @param level one of the following <code>Connection</code>
1207     * constants: <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>
1208     * , <code>Connection.TRANSACTION_READ_COMMITTED</code>,
1209     * <code>Connection.TRANSACTION_REPEATABLE_READ</code>, or
1210     * <code>Connection.TRANSACTION_SERIALIZABLE</code>. (Note
1211     * that <code>Connection.TRANSACTION_NONE</code> cannot be
1212     * used because it specifies that transactions are not
1213     * supported.)
1214     * @exception SQLException if a database access error occurs or
1215     * the given parameter is not one of the <code>Connection</code>
1216     * constants <p>
1217     * @see jdbcDatabaseMetaData#supportsTransactionIsolationLevel
1218     * @see #getTransactionIsolation
1219     */

1220    public synchronized void setTransactionIsolation(int level)
1221    throws SQLException JavaDoc {
1222
1223        checkClosed();
1224
1225        switch (level) {
1226
1227            case TRANSACTION_READ_UNCOMMITTED :
1228            case TRANSACTION_READ_COMMITTED :
1229            case TRANSACTION_REPEATABLE_READ :
1230            case TRANSACTION_SERIALIZABLE :
1231                break;
1232
1233            default :
1234                throw Util.invalidArgument();
1235        }
1236
1237        try {
1238            sessionProxy.setIsolation(level);
1239        } catch (HsqlException e) {
1240            throw Util.sqlException(e);
1241        }
1242    }
1243
1244    /**
1245     * <!-- start generic documentation -->
1246     * Retrieves this <code>Connection</code>
1247     * object's current transaction isolation level. <p>
1248     *
1249     * <!-- end generic documentation -->
1250     * <!-- start release-specific documentation -->
1251     * <div class="ReleaseSpecificDocumentation">
1252     * <h3>HSQLDB-Specific Information:</h3> <p>
1253     *
1254     * HSQLDB always returns
1255     * <code>Connection.TRANSACTION_READ_UNCOMMITED</code>. <p>
1256     *
1257     * </div> <!-- end release-specific documentation -->
1258     *
1259     * @return the current transaction isolation level, which will be
1260     * one of the following constants:
1261     * <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>
1262     * , <code>Connection.TRANSACTION_READ_COMMITTED</code>,
1263     * <code>Connection.TRANSACTION_REPEATABLE_READ</code>,
1264     * <code>Connection.TRANSACTION_SERIALIZABLE</code>, or
1265     * <code>Connection.TRANSACTION_NONE</code> <p>
1266     *
1267     * Up to and including 1.7.1, TRANSACTION_READ_UNCOMMITTED is
1268     * always returned
1269     * @exception SQLException if a database access error occurs <p>
1270     * @see jdbcDatabaseMetaData#supportsTransactionIsolationLevel
1271     * @see #setTransactionIsolation setTransactionIsolation
1272     */

1273    public synchronized int getTransactionIsolation() throws SQLException JavaDoc {
1274
1275        checkClosed();
1276
1277        try {
1278            return sessionProxy.getIsolation();
1279        } catch (HsqlException e) {
1280            throw Util.sqlException(e);
1281        }
1282    }
1283
1284    /**
1285     * <!-- start generic documentation -->
1286     * Retrieves the first warning reported by calls on this
1287     * <code>Connection</code> object. If there is more than one
1288     * warning, subsequent warnings will be chained to the first
1289     * one and can be retrieved by calling the method
1290     * <code>SQLWarning.getNextWarning</code> on the warning
1291     * that was retrieved previously. <p>
1292     *
1293     * This method may not be called on a closed connection; doing so
1294     * will cause an <code>SQLException</code> to be thrown. <p>
1295     *
1296     * <B>Note:</B> Subsequent warnings will be chained to this
1297     * SQLWarning. <p>
1298     *
1299     * <!-- end generic documentation -->
1300     * <!-- start release-specific documentation -->
1301     * <div class="ReleaseSpecificDocumentation">
1302     * <h3>HSQLDB-Specific Information:</h3> <p>
1303     *
1304     * Starting with 1.7.2, HSQLDB produces warnings whenever a createStatement(),
1305     * prepareStatement() or prepareCall() invocation requests an unsupported
1306     * but defined combination of result set type, concurrency and holdability,
1307     * such that another set is substituted.
1308     *
1309     * </div> <!-- end release-specific documentation -->
1310     * @return the first <code>SQLWarning</code> object or <code>null</code>
1311     * if there are none<p>
1312     * @exception SQLException if a database access error occurs or
1313     * this method is called on a closed connection <p>
1314     * @see SQLWarning
1315     */

1316    public synchronized SQLWarning JavaDoc getWarnings() throws SQLException JavaDoc {
1317
1318        checkClosed();
1319
1320        synchronized (rootWarning_mutex) {
1321            return rootWarning;
1322        }
1323    }
1324
1325    /**
1326     * <!-- start generic documentation -->
1327     * Clears all warnings reported for this <code>Connection</code>
1328     * object. After a call to this method, the method
1329     * <code>getWarnings</code> returns null until
1330     * a new warning is reported for this Connection. <p>
1331     *
1332     * <!-- end generic documentation -->
1333     * <!-- start release-specific documentation -->
1334     * <div class="ReleaseSpecificDocumentation">
1335     * <h3>HSQLDB-Specific Information:</h3> <p>
1336     *
1337     * Before HSQLDB 1.7.2, <code>SQLWarning</code> was not
1338     * supported, and calls to this method are simply ignored. <p>
1339     *
1340     * Starting with HSQLDB 1.7.2, the standard behaviour is implemented. <p>
1341     *
1342     * </div> <!-- end release-specific documentation -->
1343     *
1344     * @exception SQLException if a database access error occurs <p>
1345     */

1346    public synchronized void clearWarnings() throws SQLException JavaDoc {
1347
1348        checkClosed();
1349
1350        synchronized (rootWarning_mutex) {
1351            rootWarning = null;
1352        }
1353    }
1354
1355    //--------------------------JDBC 2.0-----------------------------
1356

1357    /**
1358     * <!-- start generic documentation -->
1359     * Creates a <code>Statement</code> object that will generate
1360     * <code>ResultSet</code> objects with the given type and
1361     * concurrency. This method is the same as the
1362     * <code>createStatement</code> method above, but it allows the
1363     * default result set type and result set concurrency type to be
1364     * overridden. <p>
1365     *
1366     * <!-- end generic documentation -->
1367     * <!-- start release-specific documentation -->
1368     * <div class="ReleaseSpecificDocumentation">
1369     * <h3>HSQLDB-Specific Information:</h3> <p>
1370     *
1371     * Up to HSQLDB 1.6.1, support was provided only for type
1372     * <code>TYPE_FORWARD_ONLY</code>
1373     * and concurrency <code>CONCUR_READ_ONLY</code>. <p>
1374     *
1375     * Starting with HSQLDB 1.7.0, support is now provided for types
1376     * <code>TYPE_FORWARD_ONLY</code>, <I>and</I>
1377     * <code>TYPE_SCROLL_INSENSITIVE</code>,
1378     * with concurrency <code>CONCUR_READ_ONLY</code>.
1379     *
1380     * Starting with HSQLDB 1.7.2, the behaviour regarding the type and
1381     * concurrency values has changed to more closely conform to the
1382     * specification. That is, if an unsupported combination is requested,
1383     * a SQLWarning is issued on this Connection and the closest supported
1384     * combination is used instead. <p>
1385     *
1386     * <B>Notes:</B> <p>
1387     *
1388     * Up to 1.6.1, calling this method returned <code>null</code> if the
1389     * connection was already closed and a supported combination of type and
1390     * concurrency was specified. This was possibly counter-intuitive
1391     * to the expectation that an exception would be thrown for
1392     * closed connections. Starting with 1.7.0. the behaviour is to throw a
1393     * <code>SQLException</code> if the connection is closed.<p>
1394     *
1395     * </div> <!-- end release-specific documentation -->
1396     *
1397     * @param type a result set type; one of
1398     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1399     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
1400     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code> (not
1401     * supported)
1402     * @param concurrency a concurrency type; one of
1403     * <code>ResultSet.CONCUR_READ_ONLY</code>
1404     * or <code>ResultSet.CONCUR_UPDATABLE</code> (not supported)
1405     * @return a new <code>Statement</code> object that will, within
1406     * the release-specific documented limitations of support,
1407     * generate <code>ResultSet</code> objects with the given
1408     * type and concurrency
1409     * @exception SQLException if a database access error occurs or
1410     * the given parameters are not ResultSet constants
1411     * indicating a supported type and concurrency
1412     * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1413     * for jdbcConnection)
1414     */

1415    public synchronized Statement JavaDoc createStatement(int type,
1416            int concurrency) throws SQLException JavaDoc {
1417
1418        checkClosed();
1419
1420        type = xlateRSType(type);
1421        concurrency = xlateRSConcurrency(concurrency);
1422
1423        return new jdbcStatement(this, type);
1424    }
1425
1426    /**
1427     * <!-- start generic documentation -->
1428     * Creates a <code>PreparedStatement</code> object that will
1429     * generate <code>ResultSet</code> objects with the given type
1430     * and concurrency. This method is the same as the
1431     * <code>prepareStatement</code> method above, but it allows the
1432     * default result set type and result set concurrency type to be
1433     * overridden. <p>
1434     *
1435     * <!-- end generic documentation -->
1436     * <!-- start release-specific documentation -->
1437     * <div class="ReleaseSpecificDocumentation">
1438     * <h3>HSQLDB-Specific Information:</h3> <p>
1439     *
1440     * Starting with HSQLDB 1.7.2, the behaviour regarding the type and
1441     * concurrency values has changed to more closely conform to the
1442     * specification. That is, if an unsupported combination is requested,
1443     * a SQLWarning is issued on this Connection and the closest supported
1444     * combination is used instead. <p>
1445     *
1446     * Also starting with 1.7.2, the support for and behaviour of
1447     * PreparedStatment has changed. Please read the introductory section
1448     * of the documentation for org.hsqldb.jdbc.jdbcPreparedStatement.
1449     *
1450     * </div> <!-- end release-specific documentation -->
1451     *
1452     * @param sql a String object that is the SQL statement to be
1453     * sent to the database; may contain one or more ? IN
1454     * parameters
1455     * @param type a result set type; one of
1456     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1457     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
1458     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code> (not
1459     * supported)
1460     * @param concurrency a concurrency type; one of
1461     * <code>ResultSet.CONCUR_READ_ONLY</code>
1462     * or <code>ResultSet.CONCUR_UPDATABLE</code> (not supported)
1463     * @return a new PreparedStatement object containing the
1464     * pre-compiled SQL statement that will produce
1465     * <code>ResultSet</code>
1466     * objects with the given type and concurrency
1467     * @exception SQLException if a database access error occurs or
1468     * the given parameters are not ResultSet constants
1469     * indicating a supported type and concurrency
1470     * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1471     * for jdbcConnection)
1472     */

1473    public synchronized PreparedStatement JavaDoc prepareStatement(String JavaDoc sql,
1474            int type, int concurrency) throws SQLException JavaDoc {
1475
1476        checkClosed();
1477
1478        type = xlateRSType(type);
1479        concurrency = xlateRSConcurrency(concurrency);
1480
1481        try {
1482            return new jdbcPreparedStatement(this, sql, type);
1483        } catch (HsqlException e) {
1484            throw Util.sqlException(e);
1485        }
1486    }
1487
1488    /**
1489     * <!-- start generic documentation -->
1490     * Creates a <code>CallableStatement</code>
1491     * object that will generate <code>ResultSet</code> objects with
1492     * the given type and concurrency. This method is the same as the
1493     * <code>prepareCall</code> method above, but it allows the
1494     * default result set type and result set concurrency type to be
1495     * overridden. <p>
1496     *
1497     * <!-- end generic documentation -->
1498     * <!-- start release-specific documentation -->
1499     * <div class="ReleaseSpecificDocumentation">
1500     * <h3>HSQLDB-Specific Information:</h3> <p>
1501     *
1502     * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
1503     * concurrency and holdability values has changed to more closely
1504     * conform to the specification. That is, if an unsupported
1505     * combination is requrested, a SQLWarning is issued on this Connection
1506     * and the closest supported combination is used instead. <p>
1507     *
1508     * Also starting with 1.7.2, the support for and behaviour of
1509     * CallableStatement has changed. Please read the introdutory section
1510     * of the documentation for org.hsqldb.jdbc.jdbcCallableStatement.
1511     *
1512     * </div> <!-- end release-specific documentation -->
1513     *
1514     * @param sql a String object that is the SQL statement to be
1515     * sent to the database; may contain one or more ? parameters
1516     * @param resultSetType a result set type; one of
1517     * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1518     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, (not
1519     * supported) or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
1520     * (not supported)
1521     * @param resultSetConcurrency a concurrency type; one of
1522     * <code>ResultSet.CONCUR_READ_ONLY</code>
1523     * or <code>ResultSet.CONCUR_UPDATABLE</code> (not supported)
1524     * @return a new CallableStatement object containing the
1525     * pre-compiled SQL statement
1526     * @exception SQLException if a database access error occurs or
1527     * the given parameters are not <code>ResultSet</code>
1528     * constants indicating a supported type and concurrency
1529     * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1530     * for jdbcConnection)
1531     */

1532    public synchronized CallableStatement JavaDoc prepareCall(String JavaDoc sql,
1533            int resultSetType, int resultSetConcurrency) throws SQLException JavaDoc {
1534
1535        checkClosed();
1536
1537        resultSetType = xlateRSType(resultSetType);
1538        resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
1539
1540        try {
1541            return new jdbcCallableStatement(this, sql, resultSetType);
1542        } catch (HsqlException e) {
1543            throw Util.sqlException(e);
1544        }
1545    }
1546
1547    /**
1548     * <!-- start generic documentation -->
1549     * Gets the type map object associated with this connection. Unless
1550     * the application has added an entry to the type map, the map
1551     * returned will be empty.<p>
1552     *
1553     * <!-- end generic documentation -->
1554     * <!-- start release-specific documentation -->
1555     * <div class="ReleaseSpecificDocumentation">
1556     * <h3>HSQLDB-Specific Information:</h3> <p>
1557     *
1558     * HSQLDB 1.7.2 does not support this feature. Calling this
1559     * method always throws a <code>SQLException</code>, stating that the
1560     * function is not supported. <p>
1561     *
1562     * </div> <!-- end release-specific documentation -->
1563     *
1564     * @return the <code>java.util.Map</code> object associated with
1565     * this <code>Connection</code> object
1566     * @exception SQLException if a database access error occurs
1567     * (always, up to HSQLDB 1.7.0, inclusive)
1568     * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1569     * for jdbcConnection)
1570     */

1571    public synchronized Map JavaDoc getTypeMap() throws SQLException JavaDoc {
1572
1573        checkClosed();
1574
1575        throw Util.notSupported();
1576    }
1577
1578    /**
1579     * <!-- start generic documentation -->
1580     * Installs the given <code>TypeMap</code>
1581     * object as the type map for this <code>Connection</code>
1582     * object. The type map will be used for the custom mapping of
1583     * SQL structured types and distinct types.<p>
1584     *
1585     * <!-- end generic documentation -->
1586     * <!-- start release-specific documentation -->
1587     * <div class="ReleaseSpecificDocumentation">
1588     * <h3>HSQLDB-Specific Information:</h3> <p>
1589     *
1590     * HSQLDB 1.7.2 does not support this feature. Calling this
1591     * method always throws a <code>SQLException</code>, stating that
1592     * the function is not supported. <p>
1593     *
1594     * </div> <!-- end release-specific documentation -->
1595     *
1596     * @param map the <code>java.util.Map</code> object to install as
1597     * the replacement for this <code>Connection</code> object's
1598     * default type map
1599     * @exception SQLException if a database access error occurs or
1600     * the given parameter is not a <code>java.util.Map</code>
1601     * object (always, up to HSQLDB 1.7.0, inclusive)
1602     * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1603     * for jdbcConnection)
1604     * @see #getTypeMap
1605     */

1606    public synchronized void setTypeMap(Map JavaDoc map) throws SQLException JavaDoc {
1607
1608        checkClosed();
1609
1610        throw Util.notSupported();
1611    }
1612
1613// boucherb@users 20020409 - javadocs for all JDBC 3 methods
1614
// boucherb@users 20020509 - todo
1615
// start adding implementations where it is easy: Savepoints
1616
//--------------------------JDBC 3.0-----------------------------
1617

1618    /**
1619     * <!-- start generic documentation -->
1620     * Changes the holdability of
1621     * <code>ResultSet</code> objects created using this
1622     * <code>Connection</code> object to the given holdability. <p>
1623     *
1624     * <!-- end generic documentation -->
1625     * <!-- start release-specific documentation -->
1626     * <div class="ReleaseSpecificDocumentation">
1627     * <h3>HSQLDB-Specific Information:</h3> <p>
1628     *
1629     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
1630     *
1631     * As of 1.7.2, only HOLD_CURSORS_OVER_COMMIT is supported; supplying
1632     * any other value will throw an exception. <p>
1633     *
1634     * </div> <!-- end release-specific documentation -->
1635     *
1636     * @param holdability a <code>ResultSet</code> holdability
1637     * constant; one of <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1638     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1639     * @throws SQLException if a database access occurs, the given
1640     * parameter is not a <code>ResultSet</code> constant
1641     * indicating holdability, or the given holdability is not
1642     * supported
1643     * @see #getHoldability
1644     * @see ResultSet
1645     * @since JDK 1.4, HSQLDB 1.7.2
1646     */

1647//#ifdef JDBC3
1648
public synchronized void setHoldability(int holdability)
1649    throws SQLException JavaDoc {
1650
1651        checkClosed();
1652
1653        switch (holdability) {
1654
1655            case jdbcResultSet.HOLD_CURSORS_OVER_COMMIT :
1656                break;
1657
1658            case jdbcResultSet.CLOSE_CURSORS_AT_COMMIT :
1659                String JavaDoc msg = "ResultSet holdability: " + holdability; //NOI18N
1660

1661                throw Util.sqlException(Trace.FUNCTION_NOT_SUPPORTED, msg);
1662            default :
1663                throw Util.invalidArgument();
1664        }
1665    }
1666
1667//#endif JDBC3
1668

1669    /**
1670     * <!-- start generic documentation -->
1671     * Retrieves the current
1672     * holdability of <code>ResultSet</code> objects created using
1673     * this <code>Connection</code> object.<p>
1674     *
1675     * <!-- end generic documentation -->
1676     * <!-- start release-specific documentation -->
1677     * <div class="ReleaseSpecificDocumentation">
1678     * <h3>HSQLDB-Specific Information:</h3> <p>
1679     *
1680     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
1681     *
1682     * Calling this method always returns HOLD_CURSORS_OVER_COMMIT. <p>
1683     *
1684     * </div> <!-- end release-specific documentation -->
1685     *
1686     * @return the holdability, one of
1687     * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1688     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1689     * @throws SQLException if a database access occurs
1690     * @see #setHoldability
1691     * @see ResultSet
1692     * @since JDK 1.4, HSQLDB 1.7.2
1693     */

1694//#ifdef JDBC3
1695
public synchronized int getHoldability() throws SQLException JavaDoc {
1696
1697        checkClosed();
1698
1699        return jdbcResultSet.HOLD_CURSORS_OVER_COMMIT;
1700    }
1701
1702//#endif JDBC3
1703

1704    /**
1705     * <!-- start generic documentation -->
1706     * Creates an unnamed savepoint in
1707     * the current transaction and returns the new <code>Savepoint</code>
1708     * object that represents it.<p>
1709     *
1710     * <!-- end generic documentation -->
1711     * <!-- start release-specific documentation -->
1712     * <div class="ReleaseSpecificDocumentation">
1713     * <h3>HSQLDB-Specific Information:</h3> <p>
1714     *
1715     * HSQLDB 1.7.2 does not support this feature. <p>
1716     *
1717     * Calling this method always throws a <code>SQLException</code>,
1718     * stating that the function is not supported. <p>
1719     *
1720     * Use setSavepoint(String name) instead <p>
1721     *
1722     * </div> <!-- end release-specific documentation -->
1723     *
1724     * @return the new <code>Savepoint</code> object
1725     * @exception SQLException if a database access error occurs or
1726     * this <code>Connection</code> object is currently in
1727     * auto-commit mode
1728     * @see jdbcSavepoint
1729     * @see java.sql.Savepoint
1730     * @since JDK 1.4, HSQLDB 1.7.2
1731     */

1732//#ifdef JDBC3
1733
public synchronized Savepoint JavaDoc setSavepoint() throws SQLException JavaDoc {
1734
1735        checkClosed();
1736
1737        throw Util.notSupported();
1738    }
1739
1740//#endif JDBC3
1741

1742    /**
1743     * <!-- start generic documentation -->
1744     * Creates a savepoint with the
1745     * given name in the current transaction and returns the new
1746     * <code>Savepoint</code> object that represents it. <p>
1747     *
1748     * <!-- end generic documentation -->
1749     *
1750     * @param name a <code>String</code> containing the name of the savepoint
1751     * @return the new <code>Savepoint</code> object
1752     * @exception SQLException if a database access error occurs or
1753     * this <code>Connection</code> object is currently in
1754     * auto-commit mode
1755     *
1756     * @see jdbcSavepoint
1757     * @see java.sql.Savepoint
1758     * @since JDK 1.4, HSQLDB 1.7.2
1759     */

1760//#ifdef JDBC3
1761
public synchronized Savepoint JavaDoc setSavepoint(String JavaDoc name)
1762    throws SQLException JavaDoc {
1763
1764        Result req;
1765
1766        checkClosed();
1767
1768        if (name == null) {
1769            String JavaDoc msg = "name is null";
1770
1771            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1772        }
1773
1774        req = Result.newSetSavepointRequest(name);
1775
1776        try {
1777            sessionProxy.execute(req);
1778        } catch (HsqlException e) {
1779            Util.throwError(e);
1780        }
1781
1782        return new jdbcSavepoint(name, this);
1783    }
1784
1785//#endif JDBC3
1786

1787    /**
1788     * <!-- start generic documentation -->
1789     * Undoes all changes made after
1790     * the given <code>Savepoint</code> object was set. <p>
1791     *
1792     * This method should be used only when auto-commit has been
1793     * disabled. <p>
1794     *
1795     * <!-- end generic documentation -->
1796     *
1797     * @param savepoint the <code>Savepoint</code> object to roll back to
1798     * @exception SQLException if a database access error occurs,
1799     * the <code>Savepoint</code> object is no longer valid,
1800     * or this <code>Connection</code> object is currently in
1801     * auto-commit mode
1802     * @see jdbcSavepoint
1803     * @see java.sql.Savepoint
1804     * @see #rollback
1805     * @since JDK 1.4, HSQLDB 1.7.2
1806     */

1807//#ifdef JDBC3
1808
public synchronized void rollback(Savepoint JavaDoc savepoint)
1809    throws SQLException JavaDoc {
1810
1811        String JavaDoc msg;
1812        jdbcSavepoint sp;
1813        Result req;
1814
1815        checkClosed();
1816
1817        if (savepoint == null) {
1818            msg = "savepoint is null";
1819
1820            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1821        }
1822
1823        try {
1824            if (sessionProxy.isAutoCommit()) {
1825                msg = "connection is autocommit";
1826
1827                throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1828            }
1829        } catch (HsqlException e) {
1830            throw Util.sqlException(e);
1831        }
1832
1833// fredt - might someone call this with a Savepoint from a different driver???
1834
if (!(savepoint instanceof jdbcSavepoint)) {
1835            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT);
1836        }
1837
1838        sp = (jdbcSavepoint) savepoint;
1839
1840        if (this != sp.connection) {
1841            msg = savepoint + " was not issued on this connection";
1842
1843            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1844        }
1845
1846        req = Result.newRollbackToSavepointRequest(sp.name);
1847
1848        try {
1849            Result result = sessionProxy.execute(req);
1850
1851            if (result.isError()) {
1852                Util.throwError(result);
1853            }
1854        } catch (HsqlException e) {
1855            Util.throwError(e);
1856        }
1857    }
1858
1859//#endif JDBC3
1860

1861    /**
1862     * <!-- start generic documentation -->
1863     * Removes the given <code>Savepoint</code>
1864     * object from the current transaction. Any reference to the
1865     * savepoint after it have been removed will cause an
1866     * <code>SQLException</code> to be thrown. <p>
1867     *
1868     * <!-- end generic documentation -->
1869     *
1870     * @param savepoint the <code>Savepoint</code> object to be removed
1871     * @exception SQLException if a database access error occurs or
1872     * the given <code>Savepoint</code> object is not a valid
1873     * savepoint in the current transaction
1874     *
1875     * @see jdbcSavepoint
1876     * @see java.sql.Savepoint
1877     * @since JDK 1.4, HSQLDB 1.7.2
1878     */

1879//#ifdef JDBC3
1880
public synchronized void releaseSavepoint(Savepoint JavaDoc savepoint)
1881    throws SQLException JavaDoc {
1882
1883        String JavaDoc msg;
1884        jdbcSavepoint sp;
1885        Result req;
1886
1887        checkClosed();
1888
1889        if (savepoint == null) {
1890            msg = "savepoint is null";
1891
1892            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1893        }
1894
1895// fredt - might someone call this with a Savepoint from a different driver???
1896
if (!(savepoint instanceof jdbcSavepoint)) {
1897            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT);
1898        }
1899
1900        sp = (jdbcSavepoint) savepoint;
1901
1902        if (this != sp.connection) {
1903            msg = savepoint.getSavepointName()
1904                  + " was not issued on this connection";
1905
1906            throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1907        }
1908
1909        req = Result.newReleaseSavepointRequest(sp.name);
1910
1911        try {
1912            Result result = sessionProxy.execute(req);
1913
1914            if (result.isError()) {
1915                Util.throwError(result);
1916            }
1917        } catch (HsqlException e) {
1918            Util.throwError(e);
1919        }
1920    }
1921
1922//#endif JDBC3
1923

1924    /**
1925     * <!-- start generic documentation -->
1926     * Creates a <code>Statement</code>
1927     * object that will generate <code>ResultSet</code> objects with
1928     * the given type, concurrency, and holdability. This method is
1929     * the same as the <code>createStatement</code> method above, but
1930     * it allows the default result set type, concurrency, and
1931     * holdability to be overridden. <p>
1932     *
1933     * <!-- end generic documentation -->
1934     * <!-- start release-specific documentation -->
1935     * <div class="ReleaseSpecificDocumentation">
1936     * <h3>HSQLDB-Specific Information:</h3> <p>
1937     *
1938     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
1939     *
1940     * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
1941     * concurrency and holdability values has changed to more closely conform
1942     * to the specification. That is, if an unsupported combination is requested,
1943     * a SQLWarning is issued on this Connection and the closest supported
1944     * combination is used instead. <p>
1945     *
1946     * </div> <!-- end release-specific documentation -->
1947     *
1948     * @param resultSetType one of the following <code>ResultSet</code>
1949     * constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1950     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
1951     * or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
1952     * @param resultSetConcurrency one of the following
1953     * <code>ResultSet</code>
1954     * constants: <code>ResultSet.CONCUR_READ_ONLY</code> or
1955     * <code>ResultSet.CONCUR_UPDATABLE</code>
1956     * @param resultSetHoldability one of the following
1957     * code>ResultSet</code>
1958     * constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1959     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1960     * @return a new <code>Statement</code> object that will generate
1961     * <code>ResultSet</code> objects with the given type,
1962     * concurrency, and holdability
1963     * @exception SQLException if a database access error occurs or
1964     * the given parameters are not <code>ResultSet</code>
1965     * constants indicating type, concurrency, and holdability
1966     * @see ResultSet
1967     * @since JDK 1.4, HSQLDB 1.7.2
1968     */

1969//#ifdef JDBC3
1970
public synchronized Statement JavaDoc createStatement(int resultSetType,
1971            int resultSetConcurrency,
1972            int resultSetHoldability) throws SQLException JavaDoc {
1973
1974        checkClosed();
1975
1976        resultSetType = xlateRSType(resultSetType);
1977        resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
1978        resultSetHoldability = xlateRSHoldability(resultSetHoldability);
1979
1980        return new jdbcStatement(this, resultSetType);
1981    }
1982
1983//#endif JDBC3
1984

1985    /**
1986     * <!-- start generic documentation -->
1987     * Creates a <code>PreparedStatement</code>
1988     * object that will generate <code>ResultSet</code> objects with
1989     * the given type, concurrency, and holdability. <p>
1990     *
1991     * This method is the same as the <code>prepareStatement</code>
1992     * method above, but it allows the default result set type,
1993     * concurrency, and holdability to be overridden. <p>
1994     *
1995     * <!-- end generic documentation -->
1996     * <!-- start release-specific documentation -->
1997     * <div class="ReleaseSpecificDocumentation">
1998     * <h3>HSQLDB-Specific Information:</h3> <p>
1999     *
2000     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
2001     *
2002     * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
2003     * concurrency and holdability values has changed to more closely
2004     * conform to the specification. That is, if an unsupported
2005     * combination is requested, a SQLWarning is issued on this Connection
2006     * and the closest supported combination is used instead. <p>
2007     *
2008     * Also starting with 1.7.2, the support for and behaviour of
2009     * PreparedStatment has changed. Please read the introductory section
2010     * of the documentation for org.hsqldb.jdbc.jdbcPreparedStatement.
2011     *
2012     * </div> <!-- end release-specific documentation -->
2013     *
2014     * @param sql a <code>String</code> object that is the SQL
2015     * statement to be sent to the database; may contain one or
2016     * more ? IN parameters
2017     * @param resultSetType one of the following <code>ResultSet</code>
2018     * constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>,
2019     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
2020     * or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
2021     * @param resultSetConcurrency one of the following
2022     * <code>ResultSet</code>
2023     * constants: <code>ResultSet.CONCUR_READ_ONLY</code> or
2024     * <code>ResultSet.CONCUR_UPDATABLE</code>
2025     * @param resultSetHoldability one of the following
2026     * <code>ResultSet</code>
2027     * constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
2028     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
2029     * @return a new <code>PreparedStatement</code> object,
2030     * containing the pre-compiled SQL statement, that will
2031     * generate <code>ResultSet</code> objects with the given
2032     * type, concurrency, and holdability
2033     * @exception SQLException if a database access error occurs or
2034     * the given parameters are not <code>ResultSet</code>
2035     * constants indicating type, concurrency, and holdability
2036     * @see ResultSet
2037     * @since JDK 1.4, HSQLDB 1.7.2
2038     */

2039//#ifdef JDBC3
2040
public synchronized PreparedStatement JavaDoc prepareStatement(String JavaDoc sql,
2041            int resultSetType, int resultSetConcurrency,
2042            int resultSetHoldability) throws SQLException JavaDoc {
2043
2044        checkClosed();
2045
2046        resultSetType = xlateRSType(resultSetType);
2047        resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
2048        resultSetHoldability = xlateRSHoldability(resultSetHoldability);
2049
2050        try {
2051            return new jdbcPreparedStatement(this, sql, resultSetType);
2052        } catch (HsqlException e) {
2053            throw Util.sqlException(e);
2054        }
2055    }
2056
2057//#endif JDBC3
2058

2059    /**
2060     * <!-- start generic documentation -->
2061     * Creates a <code>CallableStatement</code>
2062     * object that will generate <code>ResultSet</code> objects with
2063     * the given type and concurrency. This method is the same as the
2064     * <code>prepareCall</code> method above, but it allows the
2065     * default result set type, result set concurrency type and
2066     * holdability to be overridden. <p>
2067     *
2068     * <!-- end generic documentation -->
2069     * <!-- start release-specific documentation -->
2070     * <div class="ReleaseSpecificDocumentation">
2071     * <h3>HSQLDB-Specific Information:</h3> <p>
2072     *
2073     * Starting with HSQLDB 1.7.2, this feature is supported. <p>
2074     *
2075     * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
2076     * concurrency and holdability values has changed to more closely
2077     * conform to the specification. That is, if an unsupported
2078     * combination is requrested, a SQLWarning is issued on this Connection
2079     * and the closest supported combination is used instead. <p>
2080     *
2081     * Also starting with 1.7.2, the support for and behaviour of
2082     * CallableStatment has changed. Please read the introdutory section
2083     * of the documentation for org.hsqldb.jdbc.jdbcCallableStatement.
2084     *
2085     * </div> <!-- end release-specific documentation -->
2086     *
2087     * @param sql a <code>String</code> object that is the SQL
2088     * statement to be sent to the database; may contain on or
2089     * more ? parameters
2090     * @param resultSetType one of the following <code>ResultSet</code>
2091     * constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>,
2092     * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
2093     * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
2094     * @param resultSetConcurrency one of the following
2095     * <code>ResultSet</code>
2096     * constants: <code>ResultSet.CONCUR_READ_ONLY</code> or
2097     * <code>ResultSet.CONCUR_UPDATABLE</code>
2098     * @param resultSetHoldability one of the following
2099     * <code>ResultSet</code>
2100     * constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
2101     * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
2102     * @return a new <code>CallableStatement</code> object,
2103     * containing the pre-compiled SQL statement, that will
2104     * generate <code>ResultSet</code> objects with the given
2105     * type, concurrency, and holdability
2106     * @exception SQLException if a database access error occurs or
2107     * the given parameters are not <code>ResultSet</code>
2108     * constants indicating type, concurrency, and holdability
2109     * @see ResultSet
2110     * @since JDK 1.4, HSQLDB 1.7.2
2111     */

2112//#ifdef JDBC3
2113
public synchronized CallableStatement JavaDoc prepareCall(String JavaDoc sql,
2114            int resultSetType, int resultSetConcurrency,
2115            int resultSetHoldability) throws SQLException JavaDoc {
2116
2117        checkClosed();
2118
2119        resultSetType = xlateRSType(resultSetType);
2120        resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
2121        resultSetHoldability = xlateRSHoldability(resultSetHoldability);
2122
2123        try {
2124            return new jdbcCallableStatement(this, sql, resultSetType);
2125        } catch (HsqlException e) {
2126            throw Util.sqlException(e);
2127        }
2128    }
2129
2130//#endif JDBC3
2131

2132    /**
2133     * <!-- start generic documentation -->
2134     * Creates a default <code>PreparedStatement</code>
2135     * object that has the capability to retrieve auto-generated
2136     * keys. The given constant tells the driver whether it should
2137     * make auto-generated keys available for retrieval. This
2138     * parameter is ignored if the SQL statement is not an
2139     * <code>INSERT</code> statement. <p>
2140     *
2141     * <B>Note:</B> This method is optimized for handling parametric
2142     * SQL statements that benefit from precompilation. If the driver
2143     * supports precompilation, the method <code>prepareStatement</code>
2144     * will send the statement to the database for precompilation.
2145     * Some drivers may not support precompilation. In this case, the
2146     * statement may not be sent to the database until the
2147     * <code>PreparedStatement</code>
2148     * object is executed. This has no direct effect on users;
2149     * however, it does affect which methods throw certain
2150     * SQLExceptions. <p>
2151     *
2152     * Result sets created using the returned <code>PreparedStatement</code>
2153     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
2154     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
2155     * <p>
2156     *
2157     * <!-- end generic documentation -->
2158     * <!-- start release-specific documentation -->
2159     * <div class="ReleaseSpecificDocumentation">
2160     * <h3>HSQLDB-Specific Information:</h3> <p>
2161     *
2162     * HSQLDB 1.7.2 does not support this feature. <p>
2163     *
2164     * Calling this method always throws a <code>SQLException</code>,
2165     * stating that the function is not supported. <p>
2166     *
2167     * </div> <!-- end release-specific documentation -->
2168     *
2169     * @param sql an SQL statement that may contain one or more '?'
2170     * IN parameter placeholders
2171     * @param autoGeneratedKeys a flag indicating that auto-generated
2172     * keys should be returned, one of
2173     * code>Statement.RETURN_GENERATED_KEYS</code>
2174     * or <code>Statement.NO_GENERATED_KEYS</code>.
2175     * @return a new <code>PreparedStatement</code> object,
2176     * containing the pre-compiled SQL statement, that will have
2177     * the capability of returning auto-generated keys
2178     * @exception SQLException if a database access error occurs or
2179     * the given parameter is not a <code>Statement</code>
2180     * constant indicating whether auto-generated keys should be
2181     * returned
2182     * @since JDK 1.4, HSQLDB 1.7.2
2183     */

2184//#ifdef JDBC3
2185
public synchronized PreparedStatement JavaDoc prepareStatement(String JavaDoc sql,
2186            int autoGeneratedKeys) throws SQLException JavaDoc {
2187
2188        checkClosed();
2189
2190        throw Util.notSupported();
2191    }
2192
2193//#endif JDBC3
2194

2195    /**
2196     * <!-- start generic documentation -->
2197     * Creates a default <code>PreparedStatement</code>
2198     * object capable of returning the auto-generated keys designated
2199     * by the given array. This array contains the indexes of the
2200     * columns in the target table that contain the auto-generated
2201     * keys that should be made available. This array is ignored if
2202     * the SQL statement is not an <code>INSERT</code> statement. <p>
2203     *
2204     * An SQL statement with or without IN parameters can be
2205     * pre-compiled and stored in a <code>PreparedStatement</code>
2206     * object. This object can then be used to efficiently execute
2207     * this statement multiple times. <p>
2208     *
2209     * <B>Note:</B> This method is optimized for handling parametric
2210     * SQL statements that benefit from precompilation. If the driver
2211     * supports precompilation, the method <code>prepareStatement</code>
2212     * will send the statement to the database for precompilation.
2213     * Some drivers may not support precompilation. In this case, the
2214     * statement may not be sent to the database until the
2215     * <code>PreparedStatement</code>
2216     * object is executed. This has no direct effect on users;
2217     * however, it does affect which methods throw certain
2218     * SQLExceptions. <p>
2219     *
2220     * Result sets created using the returned <code>PreparedStatement</code>
2221     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
2222     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
2223     * <p>
2224     *
2225     * <!-- end generic documentation -->
2226     * <!-- start release-specific documentation -->
2227     * <div class="ReleaseSpecificDocumentation">
2228     * <h3>HSQLDB-Specific Information:</h3> <p>
2229     *
2230     * HSQLDB 1.7.2 does not support this feature. <p>
2231     *
2232     * Calling this method always throws a <code>SQLException</code>,
2233     * stating that the function is not supported. <p>
2234     *
2235     * </div> <!-- end release-specific documentation -->
2236     *
2237     * @param sql an SQL statement that may contain one or more '?'
2238     * IN parameter placeholders
2239     * @param columnIndexes an array of column indexes indicating the
2240     * columns that should be returned from the inserted row or
2241     * rows
2242     * @return a new <code>PreparedStatement</code> object,
2243     * containing the pre-compiled statement, that is capable of
2244     * returning the auto-generated keys designated by the given
2245     * array of column indexes
2246     * @exception SQLException if a database access error occurs
2247     * @since JDK 1.4, HSQLDB 1.7.2
2248     */

2249//#ifdef JDBC3
2250
public synchronized PreparedStatement JavaDoc prepareStatement(String JavaDoc sql,
2251            int[] columnIndexes) throws SQLException JavaDoc {
2252
2253        checkClosed();
2254
2255        throw Util.notSupported();
2256    }
2257
2258//#endif JDBC3
2259

2260    /**
2261     * <!-- start generic documentation -->
2262     * Creates a default <code>PreparedStatement</code>
2263     * object capable of returning the auto-generated keys designated
2264     * by the given array. This array contains the names of the
2265     * columns in the target table that contain the auto-generated
2266     * keys that should be returned. This array is ignored if the SQL
2267     * statement is not an <code>INSERT</code> statement. <p>
2268     *
2269     * An SQL statement with or without IN parameters can be
2270     * pre-compiled and stored in a <code>PreparedStatement</code>
2271     * object. This object can then be used to efficiently execute
2272     * this statement multiple times. <p>
2273     *
2274     * <B>Note:</B> This method is optimized for handling parametric
2275     * SQL statements that benefit from precompilation. If the driver
2276     * supports precompilation, the method <code>prepareStatement</code>
2277     * will send the statement to the database for precompilation.
2278     * Some drivers may not support precompilation. In this case, the
2279     * statement may not be sent to the database until the
2280     * <code>PreparedStatement</code>
2281     * object is executed. This has no direct effect on users;
2282     * however, it does affect which methods throw certain
2283     * SQLExceptions. <p>
2284     *
2285     * Result sets created using the returned <code>PreparedStatement</code>
2286     * object will by default be type <code>TYPE_FORWARD_ONLY</code>
2287     * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
2288     * <p>
2289     *
2290     * <!-- end generic documentation -->
2291     * <!-- start release-specific documentation -->
2292     * <div class="ReleaseSpecificDocumentation">
2293     * <h3>HSQLDB-Specific Information:</h3> <p>
2294     *
2295     * HSQLDB 1.7.2 does not support this feature. <p>
2296     *
2297     * Calling this method always throws a <code>SQLException</code>,
2298     * stating that the function is not supported. <p>
2299     *
2300     * </div> <!-- end release-specific documentation -->
2301     *
2302     * @param sql an SQL statement that may contain one or more '?'
2303     * IN parameter placeholders
2304     * @param columnNames an array of column names indicating the
2305     * columns that should be returned from the inserted row or
2306     * rows
2307     * @return a new <code>PreparedStatement</code> object,
2308     * containing the pre-compiled statement, that is capable of
2309     * returning the auto-generated keys designated by the given
2310     * array of column names
2311     * @exception SQLException if a database access error occurs
2312     * @since JDK 1.4, HSQLDB 1.7.2
2313     */

2314//#ifdef JDBC3
2315
public synchronized PreparedStatement JavaDoc prepareStatement(String JavaDoc sql,
2316            String JavaDoc[] columnNames) throws SQLException JavaDoc {
2317
2318        checkClosed();
2319
2320        throw Util.notSupported();
2321    }
2322
2323//#endif JDBC3
2324
//---------------------- internal implementation ---------------------------
2325

2326    /**
2327     * Constructs a new external <code>Connection</code> to an HSQLDB
2328     * <code>Database</code>. <p>
2329     *
2330     * This constructor is called on behalf of the
2331     * <code>java.sql.DriverManager</code> when getting a
2332     * <code>Connection</code> for use in normal (external)
2333     * client code. <p>
2334     *
2335     * Internal client code, that being code located in HSQLDB SQL
2336     * functions and stored procedures, receives an INTERNAL
2337     * connection constructed by the {@link #jdbcConnection(Session)
2338     * jdbcConnection(Session)} constructor. <p>
2339     *
2340     * @param props A <code>Properties</code> object containing the connection
2341     * properties
2342     * @exception SQLException when the user/password combination is
2343     * invalid, the connection url is invalid, or the
2344     * <code>Database</code> is unavailable. <p>
2345     *
2346     * The <code>Database</code> may be unavailable for a number
2347     * of reasons, including network problems or the fact that it
2348     * may already be in use by another process.
2349     */

2350    public jdbcConnection(HsqlProperties props) throws SQLException JavaDoc {
2351
2352        String JavaDoc user = props.getProperty("user");
2353        String JavaDoc password = props.getProperty("password");
2354        String JavaDoc connType = props.getProperty("connection_type");
2355        String JavaDoc host = props.getProperty("host");
2356        int port = props.getIntegerProperty("port", 0);
2357        String JavaDoc path = props.getProperty("path");
2358        String JavaDoc database = props.getProperty("database");
2359        boolean isTLS = (connType == DatabaseURL.S_HSQLS
2360                         || connType == DatabaseURL.S_HTTPS);
2361
2362        if (user == null) {
2363            user = "SA";
2364        }
2365
2366        if (password == null) {
2367            password = "";
2368        }
2369
2370        user = user.toUpperCase(Locale.ENGLISH);
2371        password = password.toUpperCase(Locale.ENGLISH);
2372
2373        try {
2374            if (DatabaseURL.isInProcessDatabaseType(connType)) {
2375
2376/** @todo fredt - this should be the only static reference to a core class in
2377                     * the jdbc package - we may make it dynamic */

2378                sessionProxy = DatabaseManager.newSession(connType, database,
2379                        user, password, props);
2380            } else if (connType == DatabaseURL.S_HSQL
2381                       || connType == DatabaseURL.S_HSQLS) {
2382                sessionProxy = new HSQLClientConnection(host, port, path,
2383                        database, isTLS, user, password);
2384                isNetConn = true;
2385            } else if (connType == DatabaseURL.S_HTTP
2386                       || connType == DatabaseURL.S_HTTPS) {
2387                sessionProxy = new HTTPClientConnection(host, port, path,
2388                        database, isTLS, user, password);
2389                isNetConn = true;
2390            } else { // alias: type not yet implemented
2391
throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT);
2392            }
2393
2394            connProperties = props;
2395        } catch (HsqlException e) {
2396            throw Util.sqlException(e);
2397        }
2398    }
2399
2400    /**
2401     * Constructs an <code>INTERNAL</code> <code>Connection</code>,
2402     * using the specified {@link Session Session}. <p>
2403     *
2404     * This constructor is called only on behalf of an existing
2405     * <code>Session</code> (the internal parallel of a
2406     * <code>Connection</code>), to be used as a parameter to a SQL
2407     * function or stored procedure that needs to execute in the context
2408     * of that <code>Session</code>. <p>
2409     *
2410     * When a Java SQL function or stored procedure is called and its
2411     * first parameter is of type <code>Connection</code>, HSQLDB
2412     * automatically notices this and constructs an <code>INTERNAL</code>
2413     * <code>Connection</code> using the current <code>Session</code>.
2414     * HSQLDB then passes this <code>Connection</code> in the first
2415     * parameter position, moving any other parameter values
2416     * specified in the SQL statement to the right by one position.
2417     * <p>
2418     *
2419     * To read more about this, see {@link Function#getValue()}. <p>
2420     *
2421     * <B>Notes:</B> <p>
2422     *
2423     * Starting with HSQLDB 1.7.2, <code>INTERNAL</code> connections are not
2424     * closed by a call to close() or by a SQL DISCONNECT.
2425     *
2426     * For HSQLDB developers not involved with writing database
2427     * internals, this change only applies to connections obtained
2428     * automatically from the database as the first parameter to
2429     * stored procedures and SQL functions. This is mainly an issue
2430     * to developers writing custom SQL function and stored procedure
2431     * libraries for HSQLDB. Presently, it is recommended that SQL function and
2432     * stored procedure code avoid depending on closing or issuing a
2433     * DISCONNECT on a connection obtained in this manner. <p>
2434     *
2435     * @param c the Session requesting the construction of this
2436     * Connection
2437     * @exception HsqlException never (reserved for future use);
2438     * @see org.hsqldb.Function
2439     */

2440    public jdbcConnection(Session c) throws HsqlException {
2441
2442        // PRE: Session is non-null
2443
isInternal = true;
2444        sessionProxy = c;
2445    }
2446
2447    /**
2448     * The default implementation simply attempts to silently {@link
2449     * #close() close()} this <code>Connection</code>
2450     */

2451    protected void finalize() {
2452
2453        try {
2454            close();
2455        } catch (SQLException JavaDoc e) {}
2456    }
2457
2458    /**
2459     * Retrieves this connection's JDBC url.
2460     *
2461     * This method is in support of the jdbcDatabaseMetaData.getURL() method.
2462     *
2463     * @return the database connection url with which this object was
2464     * constructed
2465     */

2466    synchronized String JavaDoc getURL() throws SQLException JavaDoc {
2467
2468        checkClosed();
2469
2470        if (isInternal) {
2471            return ((Session) sessionProxy).getInternalConnectionURL();
2472        }
2473
2474        return connProperties.getProperty("url");
2475    }
2476
2477    /**
2478     * An internal check for closed connections. <p>
2479     *
2480     * @throws SQLException when the connection is closed
2481     */

2482    synchronized void checkClosed() throws SQLException JavaDoc {
2483
2484        if (isClosed) {
2485            throw Util.sqlException(Trace.CONNECTION_IS_CLOSED);
2486        }
2487    }
2488
2489    /**
2490     * Adds another SQLWarning to this Connection object's warning chain.
2491     *
2492     * @param w the SQLWarning to add to the chain
2493     */

2494    void addWarning(SQLWarning JavaDoc w) {
2495
2496        // PRE: w is never null
2497
synchronized (rootWarning_mutex) {
2498            if (rootWarning == null) {
2499                rootWarning = w;
2500            } else {
2501                rootWarning.setNextWarning(w);
2502            }
2503        }
2504    }
2505
2506    /**
2507     * Clears the warning chain without checking if this Connection is closed.
2508     */

2509    void clearWarningsNoCheck() {
2510
2511        synchronized (rootWarning_mutex) {
2512            rootWarning = null;
2513        }
2514    }
2515
2516    /**
2517     * Translates <code>ResultSet</code> type, adding to the warning
2518     * chain if the requested type is downgraded. <p>
2519     *
2520     * Up to and including HSQLDB 1.7.2, <code>TYPE_FORWARD_ONLY</code> and
2521     * <code>TYPE_SCROLL_INSENSITIVE</code> are passed through. <p>
2522     *
2523     * Starting with 1.7.2, while <code>TYPE_SCROLL_SENSITIVE</code> is
2524     * downgraded to <code>TYPE_SCROLL_INSENSITIVE</code> and an SQLWarning is
2525     * issued. <p>
2526     *
2527     * @param type of <code>ResultSet</code>; one of
2528     * <code>jdbcResultSet.TYPE_XXX</code>
2529     * @return the actual type that will be used
2530     * @throws SQLException if type is not one of the defined values
2531     */

2532    int xlateRSType(int type) throws SQLException JavaDoc {
2533
2534        SQLWarning JavaDoc w;
2535        String JavaDoc msg;
2536
2537        switch (type) {
2538
2539            case jdbcResultSet.TYPE_FORWARD_ONLY :
2540            case jdbcResultSet.TYPE_SCROLL_INSENSITIVE : {
2541                return type;
2542            }
2543            case jdbcResultSet.TYPE_SCROLL_SENSITIVE : {
2544                msg = "TYPE_SCROLL_SENSITIVE => TYPE_SCROLL_SENSITIVE";
2545                w = new SQLWarning JavaDoc(msg, "SOO10", Trace.INVALID_JDBC_ARGUMENT);
2546
2547                addWarning(w);
2548
2549                return jdbcResultSet.TYPE_SCROLL_INSENSITIVE;
2550            }
2551            default : {
2552                msg = "ResultSet type: " + type;
2553
2554                throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
2555            }
2556        }
2557    }
2558
2559    /**
2560     * Translates <code>ResultSet</code> concurrency, adding to the warning
2561     * chain if the requested concurrency is downgraded. <p>
2562     *
2563     * Starting with HSQLDB 1.7.2, <code>CONCUR_READ_ONLY</code> is
2564     * passed through while <code>CONCUR_UPDATABLE</code> is downgraded
2565     * to <code>CONCUR_READ_ONLY</code> and an SQLWarning is issued.
2566     *
2567     * @param concurrency of <code>ResultSet</code>; one of
2568     * <code>jdbcResultSet.CONCUR_XXX</code>
2569     * @return the actual concurrency that will be used
2570     * @throws SQLException if concurrency is not one of the defined values
2571     */

2572    int xlateRSConcurrency(int concurrency) throws SQLException JavaDoc {
2573
2574        SQLWarning JavaDoc w;
2575        String JavaDoc msg;
2576
2577        switch (concurrency) {
2578
2579            case jdbcResultSet.CONCUR_READ_ONLY : {
2580                return concurrency;
2581            }
2582            case jdbcResultSet.CONCUR_UPDATABLE : {
2583                msg = "CONCUR_UPDATABLE => CONCUR_READ_ONLY";
2584                w = new SQLWarning JavaDoc(msg, "SOO10", Trace.INVALID_JDBC_ARGUMENT);
2585
2586                addWarning(w);
2587
2588                return jdbcResultSet.CONCUR_READ_ONLY;
2589            }
2590            default : {
2591                msg = "ResultSet concurrency: " + concurrency;
2592
2593                throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
2594            }
2595        }
2596    }
2597
2598    /**
2599     * Translates <code>ResultSet</code> holdability, adding to the warning
2600     * chain if the requested holdability is changed from an unsupported to
2601     * a supported value. <p>
2602     *
2603     * Starting with HSQLDB 1.7.2, <code>HOLD_CURSORS_OVER_COMMIT</code> is
2604     * passed through while <code>CLOSE_CURSORS_AT_COMMIT</code> is changed
2605     * to <code>HOLD_CURSORS_OVER_COMMIT</code> and an SQLWarning is
2606     * issued. <p>
2607     *
2608     * @param holdability of <code>ResultSet</code>; one of
2609     * <code>jdbcResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
2610     * <code>jdbcResultSet.CLOSE_CURSORS_AT_COMMIT</code>
2611     * @return the actual holdability that will be used
2612     * @throws SQLException if holdability is not one of the defined values
2613     */

2614    int xlateRSHoldability(int holdability) throws SQLException JavaDoc {
2615
2616        SQLWarning JavaDoc w;
2617        String JavaDoc msg;
2618
2619        switch (holdability) {
2620
2621            case jdbcResultSet.HOLD_CURSORS_OVER_COMMIT : {
2622                return holdability;
2623            }
2624            case jdbcResultSet.CLOSE_CURSORS_AT_COMMIT : {
2625                msg = "CLOSE_CURSORS_AT_COMMIT => HOLD_CURSORS_OVER_COMMIT";
2626                w = new SQLWarning JavaDoc(msg, "SOO10", Trace.INVALID_JDBC_ARGUMENT);
2627
2628                addWarning(w);
2629
2630                return jdbcResultSet.HOLD_CURSORS_OVER_COMMIT;
2631            }
2632            default : {
2633                msg = "ResultSet holdability: " + holdability;
2634
2635                throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
2636            }
2637        }
2638    }
2639
2640    /**
2641     * Resets this connection so it can be used again. Used when connections are
2642     * returned to a connection pool.
2643     */

2644    public void reset() throws SQLException JavaDoc {
2645
2646        try {
2647            this.sessionProxy.resetSession();
2648        } catch (HsqlException e) {
2649            throw new SQLException JavaDoc("Error resetting connection: "
2650                                   + e.getMessage());
2651        }
2652    }
2653
2654    /**
2655     * is called from within nativeSQL when the start of an JDBC escape sequence is encountered
2656     */

2657    private int onStartEscapeSequence(String JavaDoc sql, StringBuffer JavaDoc sb,
2658                                      int i) throws SQLException JavaDoc {
2659
2660        sb.setCharAt(i++, ' ');
2661
2662        i = StringUtil.skipSpaces(sql, i);
2663
2664        if (sql.regionMatches(true, i, "fn ", 0, 3)
2665                || sql.regionMatches(true, i, "oj ", 0, 3)
2666                || sql.regionMatches(true, i, "ts ", 0, 3)) {
2667            sb.setCharAt(i++, ' ');
2668            sb.setCharAt(i++, ' ');
2669        } else if (sql.regionMatches(true, i, "d ", 0, 2)
2670                   || sql.regionMatches(true, i, "t ", 0, 2)) {
2671            sb.setCharAt(i++, ' ');
2672        } else if (sql.regionMatches(true, i, "call ", 0, 5)) {
2673            i += 4;
2674        } else if (sql.regionMatches(true, i, "?= call ", 0, 8)) {
2675            sb.setCharAt(i++, ' ');
2676            sb.setCharAt(i++, ' ');
2677
2678            i += 5;
2679        } else if (sql.regionMatches(true, i, "escape ", 0, 7)) {
2680            i += 6;
2681        } else {
2682            i--;
2683
2684            throw new SQLException JavaDoc(
2685                Trace.getMessage(
2686                    Trace.jdbcConnection_nativeSQL, true, new Object JavaDoc[]{
2687                        sql.substring(i) }), "S0010",
2688                                             Trace.INVALID_JDBC_ARGUMENT);
2689        }
2690
2691        return i;
2692    }
2693}
2694
Popular Tags