0001: /* Copyright (c) 2001-2005, The HSQL Development Group
0002: * All rights reserved.
0003: *
0004: * Redistribution and use in source and binary forms, with or without
0005: * modification, are permitted provided that the following conditions are met:
0006: *
0007: * Redistributions of source code must retain the above copyright notice, this
0008: * list of conditions and the following disclaimer.
0009: *
0010: * Redistributions in binary form must reproduce the above copyright notice,
0011: * this list of conditions and the following disclaimer in the documentation
0012: * and/or other materials provided with the distribution.
0013: *
0014: * Neither the name of the HSQL Development Group nor the names of its
0015: * contributors may be used to endorse or promote products derived from this
0016: * software without specific prior written permission.
0017: *
0018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
0022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029: */
0030:
0031: package org.hsqldb.jdbc;
0032:
0033: import java.sql.CallableStatement;
0034: import java.sql.Connection;
0035: import java.sql.DatabaseMetaData;
0036: import java.sql.PreparedStatement;
0037: import java.sql.SQLException;
0038: import java.sql.SQLWarning;
0039: import java.sql.Statement;
0040:
0041: //#ifdef JDBC3
0042: import java.sql.Savepoint;
0043:
0044: //#endif JDBC3
0045: //#ifdef JAVA2
0046: import java.util.Map;
0047:
0048: //#endif JAVA2
0049: import java.util.Locale;
0050:
0051: import org.hsqldb.DatabaseManager;
0052: import org.hsqldb.DatabaseURL;
0053: import org.hsqldb.HSQLClientConnection;
0054: import org.hsqldb.HTTPClientConnection;
0055: import org.hsqldb.HsqlException;
0056: import org.hsqldb.persist.HsqlProperties;
0057: import org.hsqldb.Result;
0058: import org.hsqldb.ResultConstants;
0059: import org.hsqldb.Session;
0060: import org.hsqldb.SessionInterface;
0061: import org.hsqldb.Trace;
0062: import org.hsqldb.lib.StringUtil;
0063:
0064: // fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
0065: // JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
0066: // boucherb@users 20020509 - added "throws SQLException" to all methods where
0067: // it was missing here but specified in the java.sql.Connection interface,
0068: // updated generic documentation to JDK 1.4, and added JDBC3 methods and docs
0069: // boucherb@users and fredt@users 20020505 - extensive review and update
0070: // of docs and behaviour to comply with java.sql specification
0071: // fredt@users 20020830 - patch 487323 by xclayl@users - better synchronization
0072: // fredt@users 20020930 - patch 1.7.1 - support for connection properties
0073: // kneedeepincode@users 20021110 - patch 635816 - correction to properties
0074: // unsaved@users 20021113 - patch 1.7.2 - SSL support
0075: // boucherb@users 2003 ??? - patch 1.7.2 - SSL support moved to factory interface
0076: // fredt@users 20030620 - patch 1.7.2 - reworked to use a SessionInterface
0077: // boucherb@users 20030801 - JavaDoc updates to reflect new connection urls
0078: // boucherb@users 20030819 - patch 1.7.2 - partial fix for broken nativeSQL method
0079: // boucherb@users 20030819 - patch 1.7.2 - SQLWarning cases implemented
0080:
0081: /**
0082: * <!-- start generic documentation -->
0083: * A connection (session) with a specific database. Within the context
0084: * of a Connection, SQL statements are executed and results
0085: * are returned. <p>
0086: *
0087: * A Connection's database is able to provide information describing
0088: * its tables, its supported SQL grammar, its stored procedures, the
0089: * capabilities of this connection, and so on. This information is
0090: * obtained with the <code>getMetaData</code> method. <p>
0091: *
0092: * <B>Note:</B> By default the Connection automatically commits
0093: * changes after executing each statement. If auto commit has been
0094: * disabled, an explicit commit must be done or database changes will
0095: * not be saved. <p>
0096: *
0097: * <!-- end generic documentation -->
0098: * <!-- start release-specific documentation -->
0099: * <div class="ReleaseSpecificDocumentation">
0100: *
0101: * <hr>
0102: *
0103: * <b>HSQLDB-Specific Information:</b> <p>
0104: *
0105: * To get a <code>Connection</code> to an HSQLDB database, the
0106: * following code may be used (updated to reflect the most recent
0107: * recommendations): <p>
0108: *
0109: * <hr>
0110: *
0111: * When using HSQLDB, the database connection <b><url></b> must start with
0112: * <b>'jdbc:hsqldb:'</b><p>
0113: *
0114: * Since 1.7.2, connection properties (<key-value-pairs>) may be appended
0115: * to the database connection <b><url></b>, using the form: <p>
0116: *
0117: * <blockquote>
0118: * <b>'<url>[;key=value]*'</b>
0119: * </blockquote> <p>
0120: *
0121: * Also since 1.7.2, the allowable forms of the HSQLDB database connection
0122: * <b><url></b> have been extended. However, all legacy forms continue
0123: * to work, with unchanged semantics. The extensions are as described in the
0124: * following material. <p>
0125: *
0126: * <hr>
0127: *
0128: * <b>Network Server Database Connections:</b> <p>
0129: *
0130: * The 1.7.2 {@link Server Server} database connection <b><url></b> has
0131: * changed to take one of the two following forms: <p>
0132: *
0133: * <div class="GeneralExample">
0134: * <ol>
0135: * <li> <b>'jdbc:hsqldb:hsql://host[:port][/<alias>][<key-value-pairs>]'</b>
0136: *
0137: * <li> <b>'jdbc:hsqldb:hsqls://host[:port][/<alias>][<key-value-pairs>]'</b>
0138: * (with TLS).
0139: * </ol>
0140: * </div> <p>
0141: *
0142: * The 1.7.2 {@link WebServer WebServer} database connection <b><url></b>
0143: * also changes to take one of two following forms: <p>
0144: *
0145: * <div class="GeneralExample">
0146: * <ol>
0147: * <li> <b>'jdbc:hsqldb:http://host[:port][/<alias>][<key-value-pairs>]'</b>
0148: *
0149: * <li> <b>'jdbc:hsqldb:https://host[:port][/<alias>][<key-value-pairs>]'</b>
0150: * (with TLS).
0151: * </ol>
0152: * </div><p>
0153: *
0154: * In both network server database connection <b><url></b> forms, the
0155: * optional <b><alias></b> component is used to identify one of possibly
0156: * several database instances available at the indicated host and port. If the
0157: * <b><alias></b> component is omitted, then a connection is made to the
0158: * network server's default database instance. <p>
0159: *
0160: * For more information on server configuration regarding mounting multiple
0161: * databases and assigning them <b><alias></b> values, please read the
0162: * Java API documentation for {@link org.hsqldb.Server Server} and related
0163: * chapters in the general documentation, especially the Advanced Users
0164: * Guide. <p>
0165: *
0166: * <hr>
0167: *
0168: * <b>Transient, In-Process Database Connections:</b> <p>
0169: *
0170: * The 1.7.2 100% in-memory (transient, in-process) database connection
0171: * <b><url></b> takes one of the two following forms: <p>
0172: *
0173: * <div class="GeneralExample">
0174: * <ol>
0175: * <li> <b>'jdbc:hsqldb:.[<key-value-pairs>]'</b>
0176: * (the legacy form, extended)
0177: *
0178: * <li> <b>'jdbc:hsqldb:mem:<alias>[<key-value-pairs>]'</b>
0179: * (the new form)
0180: * </ol>
0181: * </div> <p>
0182: *
0183: * With the 1.7.2 transient, in-process database connection <b><url></b>,
0184: * the <b><alias></b> component is the key used to look up a transient,
0185: * in-process database instance amongst the collection of all such instances
0186: * already in existence within the current class loading context in the
0187: * current JVM. If no such instance exists, one <em>may</em> be automatically
0188: * created and mapped to the <b><alias></b>, as governed by the
0189: * <b>'ifexists=true|false'</b> connection property. <p>
0190: *
0191: * <hr>
0192: *
0193: * <b>Persistent, In-Process Database Connections:</b> <p>
0194: *
0195: * The 1.7.2 standalone (persistent, in-process) database connection
0196: * <b><url></b> takes one of the three following forms: <p>
0197: *
0198: * <div class="GeneralExample">
0199: * <ol>
0200: * <li> <b>'jdbc:hsqldb:<path>[<key-value-pairs>]'</b>
0201: * (the legacy form, extended)
0202: *
0203: * <li> <b>'jdbc:hsqldb:file:<path>[<key-value-pairs>]'</b>
0204: * (same semantics as the legacy form)
0205: *
0206: * <li> <b>'jdbc:hsqldb:res:<path>[<key-value-pairs>]'</b>
0207: * (new form with 'files_in_jar' semantics)
0208: * </ol>
0209: * </div> <p>
0210: *
0211: * For the persistent, in-process database connection <b><url></b>,
0212: * the <b><path></b> component is the path prefix common to all of
0213: * the files that compose the database. <p>
0214: *
0215: * As of 1.7.2, although other files may be involved (such as transient working
0216: * files and/or TEXT table CSV data source files), the essential set that may,
0217: * at any particular point in time, compose an HSQLDB database are: <p>
0218: *
0219: * <div class="GeneralExample">
0220: * <ul>
0221: * <li><path>.properties
0222: * <li><path>.script
0223: * <li><path>.log
0224: * <li><path>.data
0225: * <li><path>.backup
0226: * <li><path>.lck
0227: * </ul>
0228: * </div> <p>
0229: *
0230: * For example: <b>'jdbc:hsqldb:file:test'</b> connects to a database
0231: * composed of some subset of the files listed above, where the expansion
0232: * of <b><path></b> is <b>'test'</b> prefixed with the path of the
0233: * working directory fixed at the time the JVM is started. <p>
0234: *
0235: * Under <em>Windows</em> <sup><font size="-2">TM</font> </sup>, <b>
0236: * 'jdbc:hsqldb:file:c:\databases\test'</b> connects to a database located
0237: * on drive <b>'C:'</b> in the directory <b>'databases'</b>, composed
0238: * of some subset of the files: <p>
0239: *
0240: * <pre class="GeneralExample">
0241: * C:\
0242: * +--databases\
0243: * +--test.properties
0244: * +--test.script
0245: * +--test.log
0246: * +--test.data
0247: * +--test.backup
0248: * +--test.lck
0249: * </pre>
0250: *
0251: * Under most variations of UNIX, <b>'jdbc:hsqldb:file:/databases/test'</b>
0252: * connects to a database located in the directory <b>'databases'</b> directly
0253: * under root, once again composed of some subset of the files: <p>
0254: *
0255: * <pre class="GeneralExample">
0256: * /
0257: * +--databases/
0258: * +--test.properties
0259: * +--test.script
0260: * +--test.log
0261: * +--test.data
0262: * +--test.backup
0263: * +--test.lck
0264: * </pre>
0265: *
0266: * <b>Some Guidelines:</b> <p>
0267: *
0268: * <ol>
0269: * <li> Both relative and absolute database file paths are supported. <p>
0270: *
0271: * <li> Relative database file paths can be specified in a platform independent
0272: * manner as: <b>'[dir1/dir2/.../dirn/]<file-name-prefix>'</b>. <p>
0273: *
0274: * <li> Specification of absolute file paths is operating-system specific.<br>
0275: * Please read your OS file system documentation. <p>
0276: *
0277: * <li> Specification of network mounts may be operating-system specific.<br>
0278: * Please read your OS file system documentation. <p>
0279: *
0280: * <li> Special care may be needed w.r.t. file path specifications
0281: * containing whitespace, mixed-case, special characters and/or
0282: * reserved file names.<br>
0283: * Please read your OS file system documentation. <p>
0284: * </ol> <p>
0285: *
0286: * <b>Note:</b> Versions of HSQLDB previous to 1.7.0 did not support creating
0287: * directories along the file path specified in the persistent, in-process mode
0288: * database connection <b><url></b> form, in the case that they did
0289: * not already exist. Starting with HSQLDB 1.7.0, directories <i>will</i>
0290: * be created if they do not already exist., but only if HSQLDB is built under
0291: * a version of the compiler greater than JDK 1.1.x. <p>
0292: *
0293: * <b>res: Connections</b><p>
0294: *
0295: * The new <b>'jdbc:hsqldb:res:<path>'</b> database connection
0296: * <b><url></b> has different semantics than the
0297: * <b>'jdbc:hsqldb:file:<path>'</b> form. The semantics are similar to
0298: * those of a <b>'files_readonly'</b> database, but with some additional
0299: * points to consider. <p>
0300: *
0301: * Specifically, the <b>'<path>'</b> component of a <b>res:</b> type
0302: * database connection <b><url></b> is used to obtain resource URL
0303: * objects and thereby read the database files as resources on the class path.
0304: * Moreover, the URL objects <i>must</i> point only to resources contained
0305: * in one or more jars on the class path (must be jar protocol). <p>
0306: *
0307: * This restriction is enforced to avoid the unfortunate situation in which,
0308: * because <b>res:</b> database instances do not create a <path>.lck file
0309: * (they are strictly files-read-only) and because the <b><path></b>
0310: * components of <b>res:</b> and <b>file:</b> database URIs are not checked
0311: * for file system equivalence, it is possible for the same database files to
0312: * be accessed concurrently by both <b>file:</b> and <b>res:</b> database
0313: * instances. That is, without this restriction, it is possible that
0314: * <path>.data and <path>.properties file content may be written
0315: * by a <b>file:</b> database instance without the knowlege or cooperation
0316: * of a <b>res:</b> database instance open on the same files, potentially
0317: * resulting in unexpected database errors, inconsistent operation
0318: * and/or data corruption. <p>
0319: *
0320: * In short, a <b>res:</b> type database connection <b><url></b> is
0321: * designed specifically to connect to a <b>'files_in_jar'</b> mode database
0322: * instance, which in turn is designed specifically to operate under
0323: * <em>Java WebStart</em><sup><font size="-2">TM</font></sup> and
0324: * <em>Java Applet</em><sup><font size="-2">TM</font></sup>configurations,
0325: * where co-locating the database files in the jars that make up the
0326: * <em>WebStart</em> application or Applet avoids the need for special security
0327: * configuration or code signing. <p>
0328: *
0329: * <b>Note:</b> Since it is difficult and often nearly impossible to determine
0330: * or control at runtime from where all classes are being loaded or which class
0331: * loader is doing the loading under <b>'files_in_jar'</b> semantics, the
0332: * <b><path></b> component of the res: database connection
0333: * <b><url></b> is always taken to be relative to the default package.
0334: * That is, if the <b><path></b> component does not start with '/', then
0335: * '/' is prepended when obtaining the resource URLs used to read the database
0336: * files. <p>
0337: *
0338: * <hr>
0339: *
0340: * For more information about HSQLDB file structure, various database modes
0341: * and other attributes such as those controlled through the HSQLDB properties
0342: * files, please read the general documentation, especially the Advanced Users
0343: * Guide. <p>
0344: *
0345: * <hr>
0346: *
0347: * <b>JRE 1.1.x Notes:</b> <p>
0348: *
0349: * In general, JDBC 2 support requires Java 1.2 and above, and JDBC3 requires
0350: * Java 1.4 and above. In HSQLDB, support for methods introduced in different
0351: * versions of JDBC depends on the JDK version used for compiling and building
0352: * HSQLDB.<p>
0353: *
0354: * Since 1.7.0, it is possible to build the product so that
0355: * all JDBC 2 methods can be called while executing under the version 1.1.x
0356: * <em>Java Runtime Environment</em><sup><font size="-2">TM</font></sup>.
0357: * However, in addition to this technique requiring explicit casts to the
0358: * org.hsqldb.jdbcXXX classes, some of the method calls also require
0359: * <code>int</code> values that are defined only in the JDBC 2 or greater
0360: * version of
0361: * <a href="http://java.sun.com/j2se/1.4/docs/api/java/sql/ResultSet.html">
0362: * <code>ResultSet</code></a> interface. For this reason, when the
0363: * product is compiled under JDK 1.1.x, these values are defined
0364: * in {@link org.hsqldb.jdbc.jdbcResultSet jdbcResultSet}. <p>
0365: *
0366: * In a JRE 1.1.x environment, calling JDBC 2 methods that take or return the
0367: * JDBC2-only <code>ResultSet</code> values can be achieved by referring
0368: * to them in parameter specifications and return value comparisons,
0369: * respectively, as follows: <p>
0370: *
0371: * <pre class="JavaCodeExample">
0372: * jdbcResultSet.FETCH_FORWARD
0373: * jdbcResultSet.TYPE_FORWARD_ONLY
0374: * jdbcResultSet.TYPE_SCROLL_INSENSITIVE
0375: * jdbcResultSet.CONCUR_READ_ONLY
0376: * // etc.
0377: * </pre>
0378: *
0379: * However, please note that code written to use HSQLDB JDBC 2 features under
0380: * JDK 1.1.x will not be compatible for use with other JDBC 2 drivers. Please
0381: * also note that this feature is offered solely as a convenience to developers
0382: * who must work under JDK 1.1.x due to operating constraints, yet wish to
0383: * use some of the more advanced features available under the JDBC 2
0384: * specification. <p>
0385: *
0386: * <hr>
0387: *
0388: * (fredt@users)<br>
0389: * (boucherb@users)<p>
0390: *
0391: * </div> <!-- end release-specific documentation -->
0392: * @author boucherb@users
0393: * @author fredt@users
0394: * @version 1.7.2
0395: * @see org.hsqldb.jdbcDriver
0396: * @see jdbcStatement
0397: * @see jdbcPreparedStatement
0398: * @see jdbcCallableStatement
0399: * @see jdbcResultSet
0400: * @see jdbcDatabaseMetaData
0401: */
0402: public class jdbcConnection implements Connection {
0403:
0404: // ---------------------------- Common Attributes --------------------------
0405:
0406: /**
0407: * Properties for the connection
0408: *
0409: */
0410: HsqlProperties connProperties;
0411:
0412: /**
0413: * This connection's interface to the corresponding Session
0414: * object in the database engine.
0415: */
0416: SessionInterface sessionProxy;
0417:
0418: /**
0419: * Is this an internal connection?
0420: */
0421: boolean isInternal;
0422:
0423: /** Is this connection to a network server instance. */
0424: protected boolean isNetConn;
0425:
0426: /**
0427: * Is this connection closed?
0428: */
0429: boolean isClosed;
0430:
0431: /** The first warning in the chain. Null if there are no warnings. */
0432: private SQLWarning rootWarning;
0433:
0434: /** Synchronizes concurrent modification of the warning chain */
0435: private Object rootWarning_mutex = new Object();
0436:
0437: /**
0438: * The set of open Statement objects returned by this Connection from
0439: * calls to createStatement, prepareCall and prepareStatement. This is
0440: * used solely for closing the statements when this Connection is closed.
0441: */
0442: /*
0443: private org.hsqldb.lib.HashSet statementSet =
0444: new org.hsqldb.lib.HashSet();
0445: */
0446:
0447: // ----------------------------------- JDBC 1 -------------------------------
0448: /**
0449: * <!-- start generic documentation -->
0450: * Creates a <code>Statement</code>
0451: * object for sending SQL statements to the database. SQL
0452: * statements without parameters are normally executed using
0453: * <code>Statement</code> objects. If the same SQL statement is
0454: * executed many times, it may be more efficient to use a
0455: * <code>PreparedStatement</code> object.<p>
0456: *
0457: * Result sets created using the returned <code>Statement</code>
0458: * object will by default be type <code>TYPE_FORWARD_ONLY</code>
0459: * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.<p>
0460: *
0461: * <!-- end generic documentation -->
0462: * <!-- start release-specific documentation -->
0463: * <div class="ReleaseSpecificDocumentation">
0464: * <h3>HSQLDB-Specific Information:</h3> <p>
0465: *
0466: * Starting with HSQLDB 1.7.2, support for precompilation at the engine level
0467: * has been implemented, so it is now much more efficient and performant
0468: * to use a <code>PreparedStatement</code> object if the same SQL statement
0469: * is executed many times. <p>
0470: *
0471: * Up to 1.6.1, HSQLDB supported <code>TYPE_FORWARD_ONLY</code> -
0472: * <code>CONCUR_READ_ONLY</code> results only, so <code>ResultSet</code>
0473: * objects created using the returned <code>Statement</code>
0474: * object would <I>always</I> be type <code>TYPE_FORWARD_ONLY</code>
0475: * with <code>CONCUR_READ_ONLY</code> concurrency. <p>
0476: *
0477: * Starting with 1.7.0, HSQLDB also supports
0478: * <code>TYPE_SCROLL_INSENSITIVE</code> results. <p>
0479: *
0480: * <b>Notes:</b> <p>
0481: *
0482: * Up to 1.6.1, calling this method returned <code>null</code> if the
0483: * connection was already closed. This was possibly counter-intuitive
0484: * to the expectation that an exception would be thrown for
0485: * closed connections. Starting with 1.7.0. the behaviour is to throw a
0486: * <code>SQLException</code> if the connection is closed. <p>
0487: *
0488: * </div> <!-- end release-specific documentation -->
0489: *
0490: * @return a new default Statement object
0491: * @throws SQLException if a database access error occurs<p>
0492: * @see #createStatement(int,int)
0493: * @see #createStatement(int,int,int)
0494: */
0495: public synchronized Statement createStatement() throws SQLException {
0496:
0497: checkClosed();
0498:
0499: Statement stmt = new jdbcStatement(this ,
0500: jdbcResultSet.TYPE_FORWARD_ONLY);
0501:
0502: return stmt;
0503: }
0504:
0505: /**
0506: * <!-- start generic documentation -->
0507: * Creates a <code>PreparedStatement</code>
0508: * object for sending parameterized SQL statements to the
0509: * database. <p>
0510: *
0511: * A SQL statement with or without IN parameters can be
0512: * pre-compiled and stored in a <code>PreparedStatement</code>
0513: * object. This object can then be used to efficiently execute
0514: * this statement multiple times. <p>
0515: *
0516: * <B>Note:</B> This method is optimized for handling parametric
0517: * SQL statements that benefit from precompilation. If the driver
0518: * supports precompilation, the method <code>prepareStatement</code>
0519: * will send the statement to the database for precompilation.
0520: * Some drivers may not support precompilation. In this case, the
0521: * statement may not be sent to the database until the
0522: * <code>PreparedStatement</code> object is executed. This has no
0523: * direct effect on users; however, it does affect which methods
0524: * throw certain <code>SQLException</code> objects.<p>
0525: *
0526: * Result sets created using the returned <code>PreparedStatement</code>
0527: * object will by default be type <code>TYPE_FORWARD_ONLY</code>
0528: * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.<p>
0529: *
0530: * <!-- end generic documentation -->
0531: * <!-- start release-specific documentation -->
0532: * <div class="ReleaseSpecificDocumentation">
0533: * <h3>HSQLDB-Specific Information:</h3> <p>
0534: *
0535: * Starting with HSQLDB 1.7.2, support for precompilation at the engine level
0536: * has been implemented, so it is now much more efficient and performant
0537: * to use a <code>PreparedStatement</code> object if the same SQL statement
0538: * is executed many times. <p>
0539: *
0540: * Starting with 1.7.2, the support for and behaviour of
0541: * PreparedStatment has changed. Please read the introductory section
0542: * of the documentation for org.hsqldb.jdbc.jdbcPreparedStatement. <P>
0543: *
0544: * </div> <!-- end release-specific documentation -->
0545: *
0546: * @param sql an SQL statement that may contain one or more '?'
0547: * IN parameter placeholders
0548: * @return a new default <code>PreparedStatement</code> object
0549: * containing the pre-compiled SQL statement
0550: * @exception SQLException if a database access error occurs <p>
0551: * @see #prepareStatement(String,int,int)
0552: */
0553: public synchronized PreparedStatement prepareStatement(String sql)
0554: throws SQLException {
0555:
0556: PreparedStatement stmt;
0557:
0558: checkClosed();
0559:
0560: try {
0561: stmt = new jdbcPreparedStatement(this , sql,
0562: jdbcResultSet.TYPE_FORWARD_ONLY);
0563:
0564: return stmt;
0565: } catch (HsqlException e) {
0566: throw Util.sqlException(e);
0567: }
0568: }
0569:
0570: /**
0571: * <!-- start generic documentation -->
0572: * Creates a <code>CallableStatement</code>
0573: * object for calling database stored procedures. The
0574: * <code>CallableStatement</code> object provides methods for setting up
0575: * its IN and OUT parameters, and methods for executing the call to a
0576: * stored procedure. <p>
0577: *
0578: * <b>Note:</b> This method is optimized for handling stored
0579: * procedure call statements. Some drivers may send the call
0580: * statement to the database when the method <code>prepareCall</code>
0581: * is done; others may wait until the <code>CallableStatement</code>
0582: * object is executed. This has no direct effect on users;
0583: * however, it does affect which method throws certain
0584: * SQLExceptions. <p>
0585: *
0586: * Result sets created using the returned <code>CallableStatement</code>
0587: * object will by default be type <code>TYPE_FORWARD_ONLY</code>
0588: * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.<p>
0589: *
0590: * <!-- end generic documentation -->
0591: * <!-- start release-specific documentation -->
0592: * <div class="ReleaseSpecificDocumentation">
0593: * <h3>HSQLDB-Specific Information:</h3> <p>
0594: *
0595: * Starting with 1.7.2, the support for and behaviour of
0596: * CallableStatement has changed. Please read the introductory section
0597: * of the documentation for org.hsqldb.jdbc.jdbcCallableStatement.
0598: *
0599: * </div> <!-- end release-specific documentation -->
0600: *
0601: * @param sql a String object that is the SQL statement to be
0602: * sent to the database; may contain one or more ?
0603: * parameters. <p>
0604: *
0605: * <B>Note:</B> Typically the SQL statement is a JDBC
0606: * function call escape string.
0607: * @return a new default <code>CallableStatement</code> object
0608: * containing the pre-compiled SQL statement
0609: * @exception SQLException if a database access error occurs <p>
0610: * @see #prepareCall(String,int,int)
0611: */
0612: public synchronized CallableStatement prepareCall(String sql)
0613: throws SQLException {
0614:
0615: CallableStatement stmt;
0616:
0617: checkClosed();
0618:
0619: try {
0620: stmt = new jdbcCallableStatement(this , sql,
0621: jdbcResultSet.TYPE_FORWARD_ONLY);
0622:
0623: return stmt;
0624: } catch (HsqlException e) {
0625: throw Util.sqlException(e);
0626: }
0627: }
0628:
0629: /**
0630: * <!-- start generic documentation -->
0631: * Converts the given SQL statement
0632: * into the system's native SQL grammar. A driver may convert the
0633: * JDBC SQL grammar into its system's native SQL grammar prior to
0634: * sending it. This method returns the native form of the
0635: * statement that the driver would have sent. <p>
0636: *
0637: * <!-- end generic documentation -->
0638: * <!-- start release-specific documentation -->
0639: * <div class="ReleaseSpecificDocumentation">
0640: * <h3>HSQLDB-Specific Information:</h3> <p>
0641: *
0642: * Up to and including 1.7.2, HSQLDB converts the JDBC SQL
0643: * grammar into the system's native SQL grammar prior to sending
0644: * it, if escape processing is set true; this method returns the
0645: * native form of the statement that the driver would send in place
0646: * of client-specified JDBC SQL grammar. <p>
0647: *
0648: * Before 1.7.2, escape processing was incomplete and
0649: * also broken in terms of support for nested escapes. <p>
0650: *
0651: * Starting with 1.7.2, escape processing is complete and handles nesting
0652: * to arbitrary depth, but enforces a very strict interpretation of the
0653: * syntax and does not detect or process SQL comments. <p>
0654: *
0655: * In essence, the HSQLDB engine directly handles the prescribed syntax
0656: * and date / time formats specified internal to the JDBC escapes.
0657: * It also directly offers the XOpen / ODBC extended scalar
0658: * functions specified available internal to the {fn ...} JDBC escape.
0659: * As such, the driver simply removes the curly braces and JDBC escape
0660: * codes in the simplest and fastest fashion possible, by replacing them
0661: * with whitespace.
0662: *
0663: * But to avoid a great deal of complexity, certain forms of input
0664: * whitespace are currently not recognised. For instance,
0665: * the driver handles "{?= call ...}" but not "{ ?= call ...} or
0666: * "{? = call ...}" <p>
0667: *
0668: * Also, comments embedded in SQL are currently not detected or
0669: * processed and thus may have unexpected effects on the output
0670: * of this method, for instance causing otherwise valid SQL to become
0671: * invalid. It is especially important to be aware of this because escape
0672: * processing is set true by default for Statement objects and is always
0673: * set true when producing a PreparedStatement from prepareStatement()
0674: * or CallableStatement from prepareCall(). Currently, it is simply
0675: * recommended to avoid submitting SQL having comments containing JDBC
0676: * escape sequence patterns and/or single or double quotation marks,
0677: * as this will avoid any potential problems.
0678: *
0679: * It is intended to implement a less strict handling of whitespace and
0680: * proper processing of SQL comments at some point in the near future,
0681: * perhaps before the final 1.7.2 release.
0682: *
0683: * In any event, 1.7.2 now correctly processes the following JDBC escape
0684: * forms to arbitrary nesting depth, but only if the exact whitespace
0685: * layout described below is used: <p>
0686: *
0687: * <ol>
0688: * <li>{call ...}
0689: * <li>{?= call ...}
0690: * <li>{fn ...}
0691: * <li>{oj ...}
0692: * <li>{d ...}
0693: * <li>{t ...}
0694: * <li>{ts ...}
0695: * </ol> <p>
0696: *
0697: * </div> <!-- end release-specific documentation -->
0698: *
0699: * @param sql a SQL statement that may contain one or more '?'
0700: * parameter placeholders
0701: * @return the native form of this statement
0702: * @throws SQLException if a database access error occurs <p>
0703: */
0704: public synchronized String nativeSQL(final String sql)
0705: throws SQLException {
0706:
0707: // boucherb@users 20030405
0708: // FIXME: does not work properly for nested escapes
0709: // e.g. {call ...(...,{ts '...'},....)} does not work
0710: // boucherb@users 20030817
0711: // TESTME: First kick at the FIXME cat done. Now lots of testing
0712: // and refinment
0713: checkClosed();
0714:
0715: // CHECKME: Thow or return null if input is null?
0716: if (sql == null || sql.length() == 0 || sql.indexOf('{') == -1) {
0717: return sql;
0718: }
0719:
0720: // boolean changed = false;
0721: int state = 0;
0722: int len = sql.length();
0723: int nest = 0;
0724: StringBuffer sb = new StringBuffer(sql.length()); //avoid 16 extra
0725: String msg;
0726:
0727: //--
0728: final int outside_all = 0;
0729: final int outside_escape_inside_single_quotes = 1;
0730: final int outside_escape_inside_double_quotes = 2;
0731:
0732: //--
0733: final int inside_escape = 3;
0734: final int inside_escape_inside_single_quotes = 4;
0735: final int inside_escape_inside_double_quotes = 5;
0736:
0737: // TODO:
0738: // final int inside_single_line_comment = 6;
0739: // final int inside_multi_line_comment = 7;
0740: // Better than old way for large inputs and for avoiding GC overhead;
0741: // toString() reuses internal char[], reducing memory requirment
0742: // and garbage items 3:2
0743: sb.append(sql);
0744:
0745: for (int i = 0; i < len; i++) {
0746: char c = sb.charAt(i);
0747:
0748: switch (state) {
0749:
0750: case outside_all: // Not inside an escape or quotes
0751: if (c == '\'') {
0752: state = outside_escape_inside_single_quotes;
0753: } else if (c == '"') {
0754: state = outside_escape_inside_double_quotes;
0755: } else if (c == '{') {
0756: i = onStartEscapeSequence(sql, sb, i);
0757:
0758: // changed = true;
0759: nest++;
0760:
0761: state = inside_escape;
0762: }
0763: break;
0764:
0765: case outside_escape_inside_single_quotes: // inside ' ' only
0766: case inside_escape_inside_single_quotes: // inside { } and ' '
0767: if (c == '\'') {
0768: state -= 1;
0769: }
0770: break;
0771:
0772: case outside_escape_inside_double_quotes: // inside " " only
0773: case inside_escape_inside_double_quotes: // inside { } and " "
0774: if (c == '"') {
0775: state -= 2;
0776: }
0777: break;
0778:
0779: case inside_escape: // inside { }
0780: if (c == '\'') {
0781: state = inside_escape_inside_single_quotes;
0782: } else if (c == '"') {
0783: state = inside_escape_inside_double_quotes;
0784: } else if (c == '}') {
0785: sb.setCharAt(i, ' ');
0786:
0787: // changed = true;
0788: nest--;
0789:
0790: state = (nest == 0) ? outside_all : inside_escape;
0791: } else if (c == '{') {
0792: i = onStartEscapeSequence(sql, sb, i);
0793:
0794: // changed = true;
0795: nest++;
0796:
0797: state = inside_escape;
0798: }
0799: }
0800: }
0801:
0802: return sb.toString();
0803: }
0804:
0805: /**
0806: * <!-- start generic documentation -->
0807: * Sets this connection's auto-commit mode to the given state.
0808: * If a connection is in auto-commit mode, then all its SQL
0809: * statements will be executed and committed as individual transactions.
0810: * Otherwise, its SQL statements are grouped into transactions that
0811: * are terminated by a call to either the method <code>commit</code> or
0812: * the method <code>rollback</code>. By default, new connections are
0813: * in auto-commit mode. <p>
0814: *
0815: * The commit occurs when the statement completes or the next
0816: * execute occurs, whichever comes first. In the case of
0817: * statements returning a <code>ResultSet</code> object, the
0818: * statement completes when the last row of the <code>ResultSet</code>
0819: * object has been retrieved or the <code>ResultSet</code> object
0820: * has been closed. In advanced cases, a single statement may
0821: * return multiple results as well as output parameter values. In
0822: * these cases, the commit occurs when all results and output
0823: * parameter values have been retrieved. <p>
0824: *
0825: * <B>NOTE:</B> If this method is called during a transaction,
0826: * the transaction is committed. <p>
0827: *
0828: * <!-- end generic documentation -->
0829: * <!-- start release-specific documentation -->
0830: * <div class="ReleaseSpecificDocumentation">
0831: * <h3>HSQLDB-Specific Information:</h3> <p>
0832: *
0833: * Up to and including HSQLDB 1.7.2, <p>
0834: *
0835: * <ol>
0836: * <li> All rows of a result set are retrieved internally <em>
0837: * before</em> the first row can actually be fetched.<br>
0838: * Therefore, a statement can be considered complete as soon as
0839: * any XXXStatement.executeXXX method returns. </li>
0840: *
0841: * <li> Multiple result sets and output parameters are not yet
0842: * supported. </li>
0843: * </ol>
0844: * <p>
0845: *
0846: * (boucherb@users) </div> <!-- end release-specific
0847: * documentation -->
0848: *
0849: * @param autoCommit <code>true</code> to enable auto-commit
0850: * mode; <code>false</code> to disable it
0851: * @exception SQLException if a database access error occurs
0852: * @see #getAutoCommit
0853: */
0854: public synchronized void setAutoCommit(boolean autoCommit)
0855: throws SQLException {
0856:
0857: checkClosed();
0858:
0859: try {
0860: sessionProxy.setAutoCommit(autoCommit);
0861: } catch (HsqlException e) {
0862: throw Util.sqlException(e);
0863: }
0864: }
0865:
0866: /**
0867: * Gets the current auto-commit state.
0868: *
0869: * @return the current state of auto-commit mode
0870: * @exception SQLException Description of the Exception
0871: * @see #setAutoCommit
0872: */
0873: public synchronized boolean getAutoCommit() throws SQLException {
0874:
0875: checkClosed();
0876:
0877: try {
0878: return sessionProxy.isAutoCommit();
0879: } catch (HsqlException e) {
0880: throw Util.sqlException(e);
0881: }
0882: }
0883:
0884: /**
0885: * <!-- start generic documentation -->
0886: * Makes all changes made since the
0887: * previous commit/rollback permanent and releases any database
0888: * locks currently held by the Connection. This method should be
0889: * used only when auto-commit mode has been disabled. <p>
0890: *
0891: * <!-- end generic documentation -->
0892: * <!-- start release-specific documentation -->
0893: * <div class="ReleaseSpecificDocumentation">
0894: * <h3>HSQLDB-Specific Information:</h3> <p>
0895: *
0896: * Starting with HSQLDB 1.7.2, savepoints are supported both
0897: * in SQL and via the JDBC interface. <p>
0898: *
0899: * Using SQL, savepoints may be set, released and used in rollback
0900: * as follows:
0901: *
0902: * <pre>
0903: * SAVEPOINT <savepoint-name>
0904: * RELEASE SAVEPOINT <savepoint-name>
0905: * ROLLBACK TO SAVEPOINT <savepoint-name>
0906: * </pre>
0907: *
0908: * </div><!-- end release-specific documentation -->
0909: *
0910: * @exception SQLException if a database access error occurs
0911: * @see #setAutoCommit
0912: */
0913: public synchronized void commit() throws SQLException {
0914:
0915: checkClosed();
0916:
0917: try {
0918: sessionProxy.commit();
0919: } catch (HsqlException e) {
0920: throw Util.sqlException(e);
0921: }
0922: }
0923:
0924: /**
0925: * <!-- start generic documentation -->
0926: * Drops all changes made since the
0927: * previous commit/rollback and releases any database locks
0928: * currently held by this Connection. This method should be used
0929: * only when auto- commit has been disabled. <p>
0930: *
0931: * <!-- end generic documentation -->
0932: * <!-- start release-specific documentation -->
0933: * <div class="ReleaseSpecificDocumentation">
0934: * <h3>HSQLDB-Specific Information:</h3> <p>
0935: *
0936: * Starting with HSQLDB 1.7.2, savepoints are fully supported both
0937: * in SQL and via the JDBC interface. <p>
0938: *
0939: * Using SQL, savepoints may be set, released and used in rollback
0940: * as follows:
0941: *
0942: * <pre>
0943: * SAVEPOINT <savepoint-name>
0944: * RELEASE SAVEPOINT <savepoint-name>
0945: * ROLLBACK TO SAVEPOINT <savepoint-name>
0946: * </pre>
0947: *
0948: * </div> <!-- end release-specific documentation -->
0949: *
0950: * @exception SQLException if a database access error occurs
0951: * @see #setAutoCommit
0952: */
0953: public synchronized void rollback() throws SQLException {
0954:
0955: checkClosed();
0956:
0957: try {
0958: sessionProxy.rollback();
0959: } catch (HsqlException e) {
0960: throw Util.sqlException(e);
0961: }
0962: }
0963:
0964: /**
0965: * <!-- start generic documentation -->
0966: * Releases this <code>Connection</code>
0967: * object's database and JDBC resources immediately instead of
0968: * waiting for them to be automatically released.<p>
0969: *
0970: * Calling the method <code>close</code> on a <code>Connection</code>
0971: * object that is already closed is a no-op. <p>
0972: *
0973: * <B>Note:</B> A <code>Connection</code> object is automatically
0974: * closed when it is garbage collected. Certain fatal errors also
0975: * close a <code>Connection</code> object. <p>
0976: *
0977: * <!-- end generic documentation -->
0978: * <!-- start release-specific documentation -->
0979: * <div class="ReleaseSpecificDocumentation">
0980: * <h3>HSQLDB-Specific Information:</h3> <p>
0981: *
0982: * In 1.7.2, <code>INTERNAL</code> <code>Connection</code>
0983: * objects are not closable from JDBC client code. <p>
0984: *
0985: * </div> <!-- end release-specific documentation -->
0986: *
0987: * @exception SQLException if a database access error occurs
0988: */
0989: public synchronized void close() throws SQLException {
0990:
0991: // Changed to synchronized above because
0992: // we would not want a sessionProxy.close()
0993: // operation to occur concurrently with a
0994: // statementXXX.executeXXX operation.
0995: if (isInternal || isClosed) {
0996: return;
0997: }
0998:
0999: isClosed = true;
1000:
1001: if (sessionProxy != null) {
1002: sessionProxy.close();
1003: }
1004:
1005: sessionProxy = null;
1006: rootWarning = null;
1007: connProperties = null;
1008: }
1009:
1010: /**
1011: * Tests to see if a Connection is closed.
1012: *
1013: * @return true if the connection is closed; false if it's still
1014: * open
1015: */
1016: public synchronized boolean isClosed() {
1017: return isClosed;
1018: }
1019:
1020: /**
1021: * <!-- start generic documentation -->
1022: * Gets the metadata regarding this connection's database.
1023: * A Connection's database is able to provide information describing
1024: * its tables, its supported SQL grammar, its stored procedures,
1025: * the capabilities of this connection, and so on. This information
1026: * is made available through a <code>DatabaseMetaData</code> object. <p>
1027: *
1028: * <!-- end generic documentation -->
1029: * <!-- start release-specific documentation -->
1030: * <div class="ReleaseSpecificDocumentation">
1031: * <h3>HSQLDB-Specific Information:</h3> <p>
1032: *
1033: * JDBC <code>DatabaseMetaData</code> methods returning
1034: * <code>ResultSet</code> were not implemented fully before 1.7.2.
1035: * Some of these methods always returned empty result sets.
1036: * Other methods did not accurately
1037: * reflect all of the MetaData for the category.
1038: * Also, some method ignored the filters provided as
1039: * parameters, returning an unfiltered result each time. <p>
1040: *
1041: * Also, the majority of methods returning <code>ResultSet</code>
1042: * threw an <code>SQLException</code> when accessed by a non-admin
1043: * user.
1044: * <hr>
1045: *
1046: * Starting with HSQLDB 1.7.2, essentially full database metadata
1047: * is supported. <p>
1048: *
1049: * For discussion in greater detail, please follow the link to the
1050: * overview for jdbcDatabaseMetaData, below.
1051: *
1052: * </div> <!-- end release-specific documentation -->
1053: *
1054: * @return a DatabaseMetaData object for this Connection
1055: * @throws SQLException if a database access error occurs
1056: * @see jdbcDatabaseMetaData
1057: */
1058: public synchronized DatabaseMetaData getMetaData()
1059: throws SQLException {
1060:
1061: checkClosed();
1062:
1063: return new jdbcDatabaseMetaData(this );
1064: }
1065:
1066: /**
1067: * <!-- start generic documentation -->
1068: * Puts this connection in read-only mode as a hint to enable
1069: * database optimizations. <p>
1070: *
1071: * <B>Note:</B> This method should not be called while in the
1072: * middle of a transaction. <p>
1073: *
1074: * <!-- end generic documentation -->
1075: * <!-- start release-specific documentation -->
1076: * <div class="ReleaseSpecificDocumentation">
1077: * <h3>HSQLDB-Specific Information:</h3> <p>
1078: *
1079: * Up to and including 1.7.2, HSQLDB will commit the current
1080: * transaction automatically when this method is called. <p>
1081: *
1082: * Additionally, HSQLDB provides a way to put a whole database in
1083: * read-only mode. This is done by manually adding the line
1084: * 'readonly=true' to the database's .properties file while the
1085: * database is offline. Upon restart, all connections will be
1086: * readonly, since the entire database will be readonly. To take
1087: * a database out of readonly mode, simply take the database
1088: * offline and remove the line 'readonly=true' from the
1089: * database's .properties file. Upon restart, the database will
1090: * be in regular (read-write) mode. <p>
1091: *
1092: * When a database is put in readonly mode, its files are opened
1093: * in readonly mode, making it possible to create CD-based
1094: * readonly databases. To create a CD-based readonly database
1095: * that has CACHED tables and whose .data file is suspected of
1096: * being highly fragmented, it is recommended that the database
1097: * first be SHUTDOWN COMPACTed before copying the database
1098: * files to CD. This will reduce the space required and may
1099: * improve access times against the .data file which holds the
1100: * CACHED table data. <p>
1101: *
1102: * Starting with 1.7.2, an alternate approach to opimizing the
1103: * .data file before creating a CD-based readonly database is to issue
1104: * the CHECKPOINT DEFRAG command followed by SHUTDOWN to take the
1105: * database offline in preparation to burn the database files to CD. <p>
1106: *
1107: * </div> <!-- end release-specific documentation -->
1108: *
1109: * @param readonly The new readOnly value
1110: * @exception SQLException if a database access error occurs
1111: */
1112: public synchronized void setReadOnly(boolean readonly)
1113: throws SQLException {
1114:
1115: checkClosed();
1116:
1117: try {
1118: sessionProxy.setReadOnly(readonly);
1119: } catch (HsqlException e) {
1120: throw Util.sqlException(e);
1121: }
1122: }
1123:
1124: /**
1125: * Tests to see if the connection is in read-only mode.
1126: *
1127: * @return true if connection is read-only and false otherwise
1128: * @exception SQLException if a database access error occurs
1129: */
1130: public synchronized boolean isReadOnly() throws SQLException {
1131:
1132: try {
1133: return sessionProxy.isReadOnly();
1134: } catch (HsqlException e) {
1135: throw Util.sqlException(e);
1136: }
1137: }
1138:
1139: /**
1140: * <!-- start generic documentation -->
1141: * Sets a catalog name in order to
1142: * select a subspace of this Connection's database in which to
1143: * work. <p>
1144: *
1145: * <!-- end generic documentation -->
1146: * <!-- start release-specific documentation -->
1147: * <div class="ReleaseSpecificDocumentation">
1148: * <h3>HSQLDB-Specific Information:</h3> <p>
1149: *
1150: * HSQLDB does not yet support catalogs and simply ignores this
1151: * request. <p>
1152: * </div>
1153: * <!-- end release-specific documentation -->
1154: *
1155: * @param catalog the name of a catalog (subspace in this
1156: * Connection object's database) in which to work (Ignored)
1157: * @throws SQLException if a database access error occurs <p>
1158: */
1159: public synchronized void setCatalog(String catalog)
1160: throws SQLException {
1161: checkClosed();
1162: }
1163:
1164: /**
1165: * <!-- start generic documentation -->
1166: * Returns the Connection's current catalog name. <p>
1167: *
1168: * <!-- end generic documentation -->
1169: * <!-- start release-specific documentation -->
1170: * <div class="ReleaseSpecificDocumentation">
1171: * <h3>HSQLDB-Specific Information:</h3> <p>
1172: *
1173: * HSQLDB does not yet support catalogs and always returns null.
1174: * <p>
1175: *
1176: * </div> <!-- end release-specific documentation -->
1177: *
1178: * @return the current catalog name or null <p>
1179: *
1180: * For HSQLDB, this is always null.
1181: * @exception SQLException Description of the Exception
1182: */
1183: public synchronized String getCatalog() throws SQLException {
1184:
1185: checkClosed();
1186:
1187: return null;
1188: }
1189:
1190: /**
1191: * <!-- start generic documentation -->
1192: * Attempts to change the transaction isolation level for this
1193: * <code>Connection</code> object to the one given. The constants
1194: * defined in the interface <code>Connection</code> are the
1195: * possible transaction isolation levels. <p>
1196: *
1197: * <B>Note:</B> If this method is called during a transaction,
1198: * the result is implementation-defined. <p>
1199: *
1200: * <!-- end generic documentation -->
1201: * <!-- start release-specific documentation -->
1202: * <div class="ReleaseSpecificDocumentation">
1203: * </div> <!-- end release-specific documentation -->
1204: *
1205: * @param level one of the following <code>Connection</code>
1206: * constants: <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>
1207: * , <code>Connection.TRANSACTION_READ_COMMITTED</code>,
1208: * <code>Connection.TRANSACTION_REPEATABLE_READ</code>, or
1209: * <code>Connection.TRANSACTION_SERIALIZABLE</code>. (Note
1210: * that <code>Connection.TRANSACTION_NONE</code> cannot be
1211: * used because it specifies that transactions are not
1212: * supported.)
1213: * @exception SQLException if a database access error occurs or
1214: * the given parameter is not one of the <code>Connection</code>
1215: * constants <p>
1216: * @see jdbcDatabaseMetaData#supportsTransactionIsolationLevel
1217: * @see #getTransactionIsolation
1218: */
1219: public synchronized void setTransactionIsolation(int level)
1220: throws SQLException {
1221:
1222: checkClosed();
1223:
1224: switch (level) {
1225:
1226: case TRANSACTION_READ_UNCOMMITTED:
1227: case TRANSACTION_READ_COMMITTED:
1228: case TRANSACTION_REPEATABLE_READ:
1229: case TRANSACTION_SERIALIZABLE:
1230: break;
1231:
1232: default:
1233: throw Util.invalidArgument();
1234: }
1235:
1236: try {
1237: sessionProxy.setIsolation(level);
1238: } catch (HsqlException e) {
1239: throw Util.sqlException(e);
1240: }
1241: }
1242:
1243: /**
1244: * <!-- start generic documentation -->
1245: * Retrieves this <code>Connection</code>
1246: * object's current transaction isolation level. <p>
1247: *
1248: * <!-- end generic documentation -->
1249: * <!-- start release-specific documentation -->
1250: * <div class="ReleaseSpecificDocumentation">
1251: * <h3>HSQLDB-Specific Information:</h3> <p>
1252: *
1253: * HSQLDB always returns
1254: * <code>Connection.TRANSACTION_READ_UNCOMMITED</code>. <p>
1255: *
1256: * </div> <!-- end release-specific documentation -->
1257: *
1258: * @return the current transaction isolation level, which will be
1259: * one of the following constants:
1260: * <code>Connection.TRANSACTION_READ_UNCOMMITTED</code>
1261: * , <code>Connection.TRANSACTION_READ_COMMITTED</code>,
1262: * <code>Connection.TRANSACTION_REPEATABLE_READ</code>,
1263: * <code>Connection.TRANSACTION_SERIALIZABLE</code>, or
1264: * <code>Connection.TRANSACTION_NONE</code> <p>
1265: *
1266: * Up to and including 1.7.1, TRANSACTION_READ_UNCOMMITTED is
1267: * always returned
1268: * @exception SQLException if a database access error occurs <p>
1269: * @see jdbcDatabaseMetaData#supportsTransactionIsolationLevel
1270: * @see #setTransactionIsolation setTransactionIsolation
1271: */
1272: public synchronized int getTransactionIsolation()
1273: throws SQLException {
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 getWarnings() throws SQLException {
1317:
1318: checkClosed();
1319:
1320: synchronized (rootWarning_mutex) {
1321: if (!isNetConn) {
1322: HsqlException[] warnings = ((Session) sessionProxy)
1323: .getAndClearWarnings();
1324:
1325: for (int i = 0; i < warnings.length; i++) {
1326: SQLWarning warning = Util.sqlWarning(warnings[i]);
1327:
1328: addWarning(warning);
1329: }
1330:
1331: // get session warnings and clear the session warnings
1332: // translate to SQLWarning objects and add to the Connection chain
1333: }
1334:
1335: return rootWarning;
1336: }
1337: }
1338:
1339: /**
1340: * <!-- start generic documentation -->
1341: * Clears all warnings reported for this <code>Connection</code>
1342: * object. After a call to this method, the method
1343: * <code>getWarnings</code> returns null until
1344: * a new warning is reported for this Connection. <p>
1345: *
1346: * <!-- end generic documentation -->
1347: * <!-- start release-specific documentation -->
1348: * <div class="ReleaseSpecificDocumentation">
1349: * <h3>HSQLDB-Specific Information:</h3> <p>
1350: *
1351: * Before HSQLDB 1.7.2, <code>SQLWarning</code> was not
1352: * supported, and calls to this method are simply ignored. <p>
1353: *
1354: * Starting with HSQLDB 1.7.2, the standard behaviour is implemented. <p>
1355: *
1356: * </div> <!-- end release-specific documentation -->
1357: *
1358: * @exception SQLException if a database access error occurs <p>
1359: */
1360: public synchronized void clearWarnings() throws SQLException {
1361:
1362: checkClosed();
1363:
1364: synchronized (rootWarning_mutex) {
1365: rootWarning = null;
1366: }
1367: }
1368:
1369: //--------------------------JDBC 2.0-----------------------------
1370:
1371: /**
1372: * <!-- start generic documentation -->
1373: * Creates a <code>Statement</code> object that will generate
1374: * <code>ResultSet</code> objects with the given type and
1375: * concurrency. This method is the same as the
1376: * <code>createStatement</code> method above, but it allows the
1377: * default result set type and result set concurrency type to be
1378: * overridden. <p>
1379: *
1380: * <!-- end generic documentation -->
1381: * <!-- start release-specific documentation -->
1382: * <div class="ReleaseSpecificDocumentation">
1383: * <h3>HSQLDB-Specific Information:</h3> <p>
1384: *
1385: * Up to HSQLDB 1.6.1, support was provided only for type
1386: * <code>TYPE_FORWARD_ONLY</code>
1387: * and concurrency <code>CONCUR_READ_ONLY</code>. <p>
1388: *
1389: * Starting with HSQLDB 1.7.0, support is now provided for types
1390: * <code>TYPE_FORWARD_ONLY</code>, <I>and</I>
1391: * <code>TYPE_SCROLL_INSENSITIVE</code>,
1392: * with concurrency <code>CONCUR_READ_ONLY</code>.
1393: *
1394: * Starting with HSQLDB 1.7.2, the behaviour regarding the type and
1395: * concurrency values has changed to more closely conform to the
1396: * specification. That is, if an unsupported combination is requested,
1397: * a SQLWarning is issued on this Connection and the closest supported
1398: * combination is used instead. <p>
1399: *
1400: * <B>Notes:</B> <p>
1401: *
1402: * Up to 1.6.1, calling this method returned <code>null</code> if the
1403: * connection was already closed and a supported combination of type and
1404: * concurrency was specified. This was possibly counter-intuitive
1405: * to the expectation that an exception would be thrown for
1406: * closed connections. Starting with 1.7.0. the behaviour is to throw a
1407: * <code>SQLException</code> if the connection is closed.<p>
1408: *
1409: * </div> <!-- end release-specific documentation -->
1410: *
1411: * @param type a result set type; one of
1412: * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1413: * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
1414: * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code> (not
1415: * supported)
1416: * @param concurrency a concurrency type; one of
1417: * <code>ResultSet.CONCUR_READ_ONLY</code>
1418: * or <code>ResultSet.CONCUR_UPDATABLE</code> (not supported)
1419: * @return a new <code>Statement</code> object that will, within
1420: * the release-specific documented limitations of support,
1421: * generate <code>ResultSet</code> objects with the given
1422: * type and concurrency
1423: * @exception SQLException if a database access error occurs or
1424: * the given parameters are not ResultSet constants
1425: * indicating a supported type and concurrency
1426: * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1427: * for jdbcConnection)
1428: */
1429: public synchronized Statement createStatement(int type,
1430: int concurrency) throws SQLException {
1431:
1432: checkClosed();
1433:
1434: type = xlateRSType(type);
1435: concurrency = xlateRSConcurrency(concurrency);
1436:
1437: return new jdbcStatement(this , type);
1438: }
1439:
1440: /**
1441: * <!-- start generic documentation -->
1442: * Creates a <code>PreparedStatement</code> object that will
1443: * generate <code>ResultSet</code> objects with the given type
1444: * and concurrency. This method is the same as the
1445: * <code>prepareStatement</code> method above, but it allows the
1446: * default result set type and result set concurrency type to be
1447: * overridden. <p>
1448: *
1449: * <!-- end generic documentation -->
1450: * <!-- start release-specific documentation -->
1451: * <div class="ReleaseSpecificDocumentation">
1452: * <h3>HSQLDB-Specific Information:</h3> <p>
1453: *
1454: * Starting with HSQLDB 1.7.2, the behaviour regarding the type and
1455: * concurrency values has changed to more closely conform to the
1456: * specification. That is, if an unsupported combination is requested,
1457: * a SQLWarning is issued on this Connection and the closest supported
1458: * combination is used instead. <p>
1459: *
1460: * Also starting with 1.7.2, the support for and behaviour of
1461: * PreparedStatment has changed. Please read the introductory section
1462: * of the documentation for org.hsqldb.jdbc.jdbcPreparedStatement.
1463: *
1464: * </div> <!-- end release-specific documentation -->
1465: *
1466: * @param sql a String object that is the SQL statement to be
1467: * sent to the database; may contain one or more ? IN
1468: * parameters
1469: * @param type a result set type; one of
1470: * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1471: * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
1472: * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code> (not
1473: * supported)
1474: * @param concurrency a concurrency type; one of
1475: * <code>ResultSet.CONCUR_READ_ONLY</code>
1476: * or <code>ResultSet.CONCUR_UPDATABLE</code> (not supported)
1477: * @return a new PreparedStatement object containing the
1478: * pre-compiled SQL statement that will produce
1479: * <code>ResultSet</code>
1480: * objects with the given type and concurrency
1481: * @exception SQLException if a database access error occurs or
1482: * the given parameters are not ResultSet constants
1483: * indicating a supported type and concurrency
1484: * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1485: * for jdbcConnection)
1486: */
1487: public synchronized PreparedStatement prepareStatement(String sql,
1488: int type, int concurrency) throws SQLException {
1489:
1490: checkClosed();
1491:
1492: type = xlateRSType(type);
1493: concurrency = xlateRSConcurrency(concurrency);
1494:
1495: try {
1496: return new jdbcPreparedStatement(this , sql, type);
1497: } catch (HsqlException e) {
1498: throw Util.sqlException(e);
1499: }
1500: }
1501:
1502: /**
1503: * <!-- start generic documentation -->
1504: * Creates a <code>CallableStatement</code>
1505: * object that will generate <code>ResultSet</code> objects with
1506: * the given type and concurrency. This method is the same as the
1507: * <code>prepareCall</code> method above, but it allows the
1508: * default result set type and result set concurrency type to be
1509: * overridden. <p>
1510: *
1511: * <!-- end generic documentation -->
1512: * <!-- start release-specific documentation -->
1513: * <div class="ReleaseSpecificDocumentation">
1514: * <h3>HSQLDB-Specific Information:</h3> <p>
1515: *
1516: * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
1517: * concurrency and holdability values has changed to more closely
1518: * conform to the specification. That is, if an unsupported
1519: * combination is requrested, a SQLWarning is issued on this Connection
1520: * and the closest supported combination is used instead. <p>
1521: *
1522: * Also starting with 1.7.2, the support for and behaviour of
1523: * CallableStatement has changed. Please read the introdutory section
1524: * of the documentation for org.hsqldb.jdbc.jdbcCallableStatement.
1525: *
1526: * </div> <!-- end release-specific documentation -->
1527: *
1528: * @param sql a String object that is the SQL statement to be
1529: * sent to the database; may contain one or more ? parameters
1530: * @param resultSetType a result set type; one of
1531: * <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1532: * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, (not
1533: * supported) or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
1534: * (not supported)
1535: * @param resultSetConcurrency a concurrency type; one of
1536: * <code>ResultSet.CONCUR_READ_ONLY</code>
1537: * or <code>ResultSet.CONCUR_UPDATABLE</code> (not supported)
1538: * @return a new CallableStatement object containing the
1539: * pre-compiled SQL statement
1540: * @exception SQLException if a database access error occurs or
1541: * the given parameters are not <code>ResultSet</code>
1542: * constants indicating a supported type and concurrency
1543: * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1544: * for jdbcConnection)
1545: */
1546: public synchronized CallableStatement prepareCall(String sql,
1547: int resultSetType, int resultSetConcurrency)
1548: throws SQLException {
1549:
1550: checkClosed();
1551:
1552: resultSetType = xlateRSType(resultSetType);
1553: resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
1554:
1555: try {
1556: return new jdbcCallableStatement(this , sql, resultSetType);
1557: } catch (HsqlException e) {
1558: throw Util.sqlException(e);
1559: }
1560: }
1561:
1562: /**
1563: * <!-- start generic documentation -->
1564: * Gets the type map object associated with this connection. Unless
1565: * the application has added an entry to the type map, the map
1566: * returned will be empty.<p>
1567: *
1568: * <!-- end generic documentation -->
1569: * <!-- start release-specific documentation -->
1570: * <div class="ReleaseSpecificDocumentation">
1571: * <h3>HSQLDB-Specific Information:</h3> <p>
1572: *
1573: * HSQLDB 1.7.2 does not support this feature. Calling this
1574: * method always throws a <code>SQLException</code>, stating that the
1575: * function is not supported. <p>
1576: *
1577: * </div> <!-- end release-specific documentation -->
1578: *
1579: * @return the <code>java.util.Map</code> object associated with
1580: * this <code>Connection</code> object
1581: * @exception SQLException if a database access error occurs
1582: * (always, up to HSQLDB 1.7.0, inclusive)
1583: * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1584: * for jdbcConnection)
1585: */
1586: public synchronized Map getTypeMap() throws SQLException {
1587:
1588: checkClosed();
1589:
1590: throw Util.notSupported();
1591: }
1592:
1593: /**
1594: * <!-- start generic documentation -->
1595: * Installs the given <code>TypeMap</code>
1596: * object as the type map for this <code>Connection</code>
1597: * object. The type map will be used for the custom mapping of
1598: * SQL structured types and distinct types.<p>
1599: *
1600: * <!-- end generic documentation -->
1601: * <!-- start release-specific documentation -->
1602: * <div class="ReleaseSpecificDocumentation">
1603: * <h3>HSQLDB-Specific Information:</h3> <p>
1604: *
1605: * HSQLDB 1.7.2 does not support this feature. Calling this
1606: * method always throws a <code>SQLException</code>, stating that
1607: * the function is not supported. <p>
1608: *
1609: * </div> <!-- end release-specific documentation -->
1610: *
1611: * @param map the <code>java.util.Map</code> object to install as
1612: * the replacement for this <code>Connection</code> object's
1613: * default type map
1614: * @exception SQLException if a database access error occurs or
1615: * the given parameter is not a <code>java.util.Map</code>
1616: * object (always, up to HSQLDB 1.7.0, inclusive)
1617: * @since JDK 1.2 (JDK 1.1.x developers: read the new overview
1618: * for jdbcConnection)
1619: * @see #getTypeMap
1620: */
1621: public synchronized void setTypeMap(Map map) throws SQLException {
1622:
1623: checkClosed();
1624:
1625: throw Util.notSupported();
1626: }
1627:
1628: // boucherb@users 20020409 - javadocs for all JDBC 3 methods
1629: // boucherb@users 20020509 - todo
1630: // start adding implementations where it is easy: Savepoints
1631: //--------------------------JDBC 3.0-----------------------------
1632:
1633: /**
1634: * <!-- start generic documentation -->
1635: * Changes the holdability of
1636: * <code>ResultSet</code> objects created using this
1637: * <code>Connection</code> object to the given holdability. <p>
1638: *
1639: * <!-- end generic documentation -->
1640: * <!-- start release-specific documentation -->
1641: * <div class="ReleaseSpecificDocumentation">
1642: * <h3>HSQLDB-Specific Information:</h3> <p>
1643: *
1644: * Starting with HSQLDB 1.7.2, this feature is supported. <p>
1645: *
1646: * As of 1.7.2, only HOLD_CURSORS_OVER_COMMIT is supported; supplying
1647: * any other value will throw an exception. <p>
1648: *
1649: * </div> <!-- end release-specific documentation -->
1650: *
1651: * @param holdability a <code>ResultSet</code> holdability
1652: * constant; one of <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1653: * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1654: * @throws SQLException if a database access occurs, the given
1655: * parameter is not a <code>ResultSet</code> constant
1656: * indicating holdability, or the given holdability is not
1657: * supported
1658: * @see #getHoldability
1659: * @see ResultSet
1660: * @since JDK 1.4, HSQLDB 1.7.2
1661: */
1662: //#ifdef JDBC3
1663: public synchronized void setHoldability(int holdability)
1664: throws SQLException {
1665:
1666: checkClosed();
1667:
1668: switch (holdability) {
1669:
1670: case jdbcResultSet.HOLD_CURSORS_OVER_COMMIT:
1671: break;
1672:
1673: case jdbcResultSet.CLOSE_CURSORS_AT_COMMIT:
1674: String msg = "ResultSet holdability: " + holdability; //NOI18N
1675:
1676: throw Util.sqlException(Trace.FUNCTION_NOT_SUPPORTED, msg);
1677: default:
1678: throw Util.invalidArgument();
1679: }
1680: }
1681:
1682: //#endif JDBC3
1683:
1684: /**
1685: * <!-- start generic documentation -->
1686: * Retrieves the current
1687: * holdability of <code>ResultSet</code> objects created using
1688: * this <code>Connection</code> object.<p>
1689: *
1690: * <!-- end generic documentation -->
1691: * <!-- start release-specific documentation -->
1692: * <div class="ReleaseSpecificDocumentation">
1693: * <h3>HSQLDB-Specific Information:</h3> <p>
1694: *
1695: * Starting with HSQLDB 1.7.2, this feature is supported. <p>
1696: *
1697: * Calling this method always returns HOLD_CURSORS_OVER_COMMIT. <p>
1698: *
1699: * </div> <!-- end release-specific documentation -->
1700: *
1701: * @return the holdability, one of
1702: * <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1703: * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1704: * @throws SQLException if a database access occurs
1705: * @see #setHoldability
1706: * @see ResultSet
1707: * @since JDK 1.4, HSQLDB 1.7.2
1708: */
1709: //#ifdef JDBC3
1710: public synchronized int getHoldability() throws SQLException {
1711:
1712: checkClosed();
1713:
1714: return jdbcResultSet.HOLD_CURSORS_OVER_COMMIT;
1715: }
1716:
1717: //#endif JDBC3
1718:
1719: /**
1720: * <!-- start generic documentation -->
1721: * Creates an unnamed savepoint in
1722: * the current transaction and returns the new <code>Savepoint</code>
1723: * object that represents it.<p>
1724: *
1725: * <!-- end generic documentation -->
1726: * <!-- start release-specific documentation -->
1727: * <div class="ReleaseSpecificDocumentation">
1728: * <h3>HSQLDB-Specific Information:</h3> <p>
1729: *
1730: * HSQLDB 1.7.2 does not support this feature. <p>
1731: *
1732: * Calling this method always throws a <code>SQLException</code>,
1733: * stating that the function is not supported. <p>
1734: *
1735: * Use setSavepoint(String name) instead <p>
1736: *
1737: * </div> <!-- end release-specific documentation -->
1738: *
1739: * @return the new <code>Savepoint</code> object
1740: * @exception SQLException if a database access error occurs or
1741: * this <code>Connection</code> object is currently in
1742: * auto-commit mode
1743: * @see jdbcSavepoint
1744: * @see java.sql.Savepoint
1745: * @since JDK 1.4, HSQLDB 1.7.2
1746: */
1747: //#ifdef JDBC3
1748: public synchronized Savepoint setSavepoint() throws SQLException {
1749:
1750: checkClosed();
1751:
1752: throw Util.notSupported();
1753: }
1754:
1755: //#endif JDBC3
1756:
1757: /**
1758: * <!-- start generic documentation -->
1759: * Creates a savepoint with the
1760: * given name in the current transaction and returns the new
1761: * <code>Savepoint</code> object that represents it. <p>
1762: *
1763: * <!-- end generic documentation -->
1764: *
1765: * @param name a <code>String</code> containing the name of the savepoint
1766: * @return the new <code>Savepoint</code> object
1767: * @exception SQLException if a database access error occurs or
1768: * this <code>Connection</code> object is currently in
1769: * auto-commit mode
1770: *
1771: * @see jdbcSavepoint
1772: * @see java.sql.Savepoint
1773: * @since JDK 1.4, HSQLDB 1.7.2
1774: */
1775: //#ifdef JDBC3
1776: public synchronized Savepoint setSavepoint(String name)
1777: throws SQLException {
1778:
1779: Result req;
1780:
1781: checkClosed();
1782:
1783: if (name == null) {
1784: String msg = "name is null";
1785:
1786: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1787: }
1788:
1789: req = Result.newSetSavepointRequest(name);
1790:
1791: try {
1792: sessionProxy.execute(req);
1793: } catch (HsqlException e) {
1794: Util.throwError(e);
1795: }
1796:
1797: return new jdbcSavepoint(name, this );
1798: }
1799:
1800: //#endif JDBC3
1801:
1802: /**
1803: * <!-- start generic documentation -->
1804: * Undoes all changes made after
1805: * the given <code>Savepoint</code> object was set. <p>
1806: *
1807: * This method should be used only when auto-commit has been
1808: * disabled. <p>
1809: *
1810: * <!-- end generic documentation -->
1811: *
1812: * @param savepoint the <code>Savepoint</code> object to roll back to
1813: * @exception SQLException if a database access error occurs,
1814: * the <code>Savepoint</code> object is no longer valid,
1815: * or this <code>Connection</code> object is currently in
1816: * auto-commit mode
1817: * @see jdbcSavepoint
1818: * @see java.sql.Savepoint
1819: * @see #rollback
1820: * @since JDK 1.4, HSQLDB 1.7.2
1821: */
1822: //#ifdef JDBC3
1823: public synchronized void rollback(Savepoint savepoint)
1824: throws SQLException {
1825:
1826: String msg;
1827: jdbcSavepoint sp;
1828: Result req;
1829:
1830: checkClosed();
1831:
1832: if (savepoint == null) {
1833: msg = "savepoint is null";
1834:
1835: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1836: }
1837:
1838: try {
1839: if (sessionProxy.isAutoCommit()) {
1840: msg = "connection is autocommit";
1841:
1842: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT,
1843: msg);
1844: }
1845: } catch (HsqlException e) {
1846: throw Util.sqlException(e);
1847: }
1848:
1849: // fredt - might someone call this with a Savepoint from a different driver???
1850: if (!(savepoint instanceof jdbcSavepoint)) {
1851: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT);
1852: }
1853:
1854: sp = (jdbcSavepoint) savepoint;
1855:
1856: if (this != sp.connection) {
1857: msg = savepoint + " was not issued on this connection";
1858:
1859: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1860: }
1861:
1862: req = Result.newRollbackToSavepointRequest(sp.name);
1863:
1864: try {
1865: Result result = sessionProxy.execute(req);
1866:
1867: if (result.isError()) {
1868: Util.throwError(result);
1869: }
1870: } catch (HsqlException e) {
1871: Util.throwError(e);
1872: }
1873: }
1874:
1875: //#endif JDBC3
1876:
1877: /**
1878: * <!-- start generic documentation -->
1879: * Removes the given <code>Savepoint</code>
1880: * object from the current transaction. Any reference to the
1881: * savepoint after it have been removed will cause an
1882: * <code>SQLException</code> to be thrown. <p>
1883: *
1884: * <!-- end generic documentation -->
1885: *
1886: * @param savepoint the <code>Savepoint</code> object to be removed
1887: * @exception SQLException if a database access error occurs or
1888: * the given <code>Savepoint</code> object is not a valid
1889: * savepoint in the current transaction
1890: *
1891: * @see jdbcSavepoint
1892: * @see java.sql.Savepoint
1893: * @since JDK 1.4, HSQLDB 1.7.2
1894: */
1895: //#ifdef JDBC3
1896: public synchronized void releaseSavepoint(Savepoint savepoint)
1897: throws SQLException {
1898:
1899: String msg;
1900: jdbcSavepoint sp;
1901: Result req;
1902:
1903: checkClosed();
1904:
1905: if (savepoint == null) {
1906: msg = "savepoint is null";
1907:
1908: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1909: }
1910:
1911: // fredt - might someone call this with a Savepoint from a different driver???
1912: if (!(savepoint instanceof jdbcSavepoint)) {
1913: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT);
1914: }
1915:
1916: sp = (jdbcSavepoint) savepoint;
1917:
1918: if (this != sp.connection) {
1919: msg = savepoint.getSavepointName()
1920: + " was not issued on this connection";
1921:
1922: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
1923: }
1924:
1925: req = Result.newReleaseSavepointRequest(sp.name);
1926:
1927: try {
1928: Result result = sessionProxy.execute(req);
1929:
1930: if (result.isError()) {
1931: Util.throwError(result);
1932: }
1933: } catch (HsqlException e) {
1934: Util.throwError(e);
1935: }
1936: }
1937:
1938: //#endif JDBC3
1939:
1940: /**
1941: * <!-- start generic documentation -->
1942: * Creates a <code>Statement</code>
1943: * object that will generate <code>ResultSet</code> objects with
1944: * the given type, concurrency, and holdability. This method is
1945: * the same as the <code>createStatement</code> method above, but
1946: * it allows the default result set type, concurrency, and
1947: * holdability to be overridden. <p>
1948: *
1949: * <!-- end generic documentation -->
1950: * <!-- start release-specific documentation -->
1951: * <div class="ReleaseSpecificDocumentation">
1952: * <h3>HSQLDB-Specific Information:</h3> <p>
1953: *
1954: * Starting with HSQLDB 1.7.2, this feature is supported. <p>
1955: *
1956: * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
1957: * concurrency and holdability values has changed to more closely conform
1958: * to the specification. That is, if an unsupported combination is requested,
1959: * a SQLWarning is issued on this Connection and the closest supported
1960: * combination is used instead. <p>
1961: *
1962: * </div> <!-- end release-specific documentation -->
1963: *
1964: * @param resultSetType one of the following <code>ResultSet</code>
1965: * constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>,
1966: * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
1967: * or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
1968: * @param resultSetConcurrency one of the following
1969: * <code>ResultSet</code>
1970: * constants: <code>ResultSet.CONCUR_READ_ONLY</code> or
1971: * <code>ResultSet.CONCUR_UPDATABLE</code>
1972: * @param resultSetHoldability one of the following
1973: * code>ResultSet</code>
1974: * constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1975: * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1976: * @return a new <code>Statement</code> object that will generate
1977: * <code>ResultSet</code> objects with the given type,
1978: * concurrency, and holdability
1979: * @exception SQLException if a database access error occurs or
1980: * the given parameters are not <code>ResultSet</code>
1981: * constants indicating type, concurrency, and holdability
1982: * @see ResultSet
1983: * @since JDK 1.4, HSQLDB 1.7.2
1984: */
1985: //#ifdef JDBC3
1986: public synchronized Statement createStatement(int resultSetType,
1987: int resultSetConcurrency, int resultSetHoldability)
1988: throws SQLException {
1989:
1990: checkClosed();
1991:
1992: resultSetType = xlateRSType(resultSetType);
1993: resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
1994: resultSetHoldability = xlateRSHoldability(resultSetHoldability);
1995:
1996: return new jdbcStatement(this , resultSetType);
1997: }
1998:
1999: //#endif JDBC3
2000:
2001: /**
2002: * <!-- start generic documentation -->
2003: * Creates a <code>PreparedStatement</code>
2004: * object that will generate <code>ResultSet</code> objects with
2005: * the given type, concurrency, and holdability. <p>
2006: *
2007: * This method is the same as the <code>prepareStatement</code>
2008: * method above, but it allows the default result set type,
2009: * concurrency, and holdability to be overridden. <p>
2010: *
2011: * <!-- end generic documentation -->
2012: * <!-- start release-specific documentation -->
2013: * <div class="ReleaseSpecificDocumentation">
2014: * <h3>HSQLDB-Specific Information:</h3> <p>
2015: *
2016: * Starting with HSQLDB 1.7.2, this feature is supported. <p>
2017: *
2018: * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
2019: * concurrency and holdability values has changed to more closely
2020: * conform to the specification. That is, if an unsupported
2021: * combination is requested, a SQLWarning is issued on this Connection
2022: * and the closest supported combination is used instead. <p>
2023: *
2024: * Also starting with 1.7.2, the support for and behaviour of
2025: * PreparedStatment has changed. Please read the introductory section
2026: * of the documentation for org.hsqldb.jdbc.jdbcPreparedStatement.
2027: *
2028: * </div> <!-- end release-specific documentation -->
2029: *
2030: * @param sql a <code>String</code> object that is the SQL
2031: * statement to be sent to the database; may contain one or
2032: * more ? IN parameters
2033: * @param resultSetType one of the following <code>ResultSet</code>
2034: * constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>,
2035: * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>,
2036: * or <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
2037: * @param resultSetConcurrency one of the following
2038: * <code>ResultSet</code>
2039: * constants: <code>ResultSet.CONCUR_READ_ONLY</code> or
2040: * <code>ResultSet.CONCUR_UPDATABLE</code>
2041: * @param resultSetHoldability one of the following
2042: * <code>ResultSet</code>
2043: * constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
2044: * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
2045: * @return a new <code>PreparedStatement</code> object,
2046: * containing the pre-compiled SQL statement, that will
2047: * generate <code>ResultSet</code> objects with the given
2048: * type, concurrency, and holdability
2049: * @exception SQLException if a database access error occurs or
2050: * the given parameters are not <code>ResultSet</code>
2051: * constants indicating type, concurrency, and holdability
2052: * @see ResultSet
2053: * @since JDK 1.4, HSQLDB 1.7.2
2054: */
2055: //#ifdef JDBC3
2056: public synchronized PreparedStatement prepareStatement(String sql,
2057: int resultSetType, int resultSetConcurrency,
2058: int resultSetHoldability) throws SQLException {
2059:
2060: checkClosed();
2061:
2062: resultSetType = xlateRSType(resultSetType);
2063: resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
2064: resultSetHoldability = xlateRSHoldability(resultSetHoldability);
2065:
2066: try {
2067: return new jdbcPreparedStatement(this , sql, resultSetType);
2068: } catch (HsqlException e) {
2069: throw Util.sqlException(e);
2070: }
2071: }
2072:
2073: //#endif JDBC3
2074:
2075: /**
2076: * <!-- start generic documentation -->
2077: * Creates a <code>CallableStatement</code>
2078: * object that will generate <code>ResultSet</code> objects with
2079: * the given type and concurrency. This method is the same as the
2080: * <code>prepareCall</code> method above, but it allows the
2081: * default result set type, result set concurrency type and
2082: * holdability to be overridden. <p>
2083: *
2084: * <!-- end generic documentation -->
2085: * <!-- start release-specific documentation -->
2086: * <div class="ReleaseSpecificDocumentation">
2087: * <h3>HSQLDB-Specific Information:</h3> <p>
2088: *
2089: * Starting with HSQLDB 1.7.2, this feature is supported. <p>
2090: *
2091: * Starting with HSQLDB 1.7.2, the behaviour regarding the type,
2092: * concurrency and holdability values has changed to more closely
2093: * conform to the specification. That is, if an unsupported
2094: * combination is requrested, a SQLWarning is issued on this Connection
2095: * and the closest supported combination is used instead. <p>
2096: *
2097: * Also starting with 1.7.2, the support for and behaviour of
2098: * CallableStatment has changed. Please read the introdutory section
2099: * of the documentation for org.hsqldb.jdbc.jdbcCallableStatement.
2100: *
2101: * </div> <!-- end release-specific documentation -->
2102: *
2103: * @param sql a <code>String</code> object that is the SQL
2104: * statement to be sent to the database; may contain on or
2105: * more ? parameters
2106: * @param resultSetType one of the following <code>ResultSet</code>
2107: * constants: <code>ResultSet.TYPE_FORWARD_ONLY</code>,
2108: * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
2109: * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
2110: * @param resultSetConcurrency one of the following
2111: * <code>ResultSet</code>
2112: * constants: <code>ResultSet.CONCUR_READ_ONLY</code> or
2113: * <code>ResultSet.CONCUR_UPDATABLE</code>
2114: * @param resultSetHoldability one of the following
2115: * <code>ResultSet</code>
2116: * constants: <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
2117: * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
2118: * @return a new <code>CallableStatement</code> object,
2119: * containing the pre-compiled SQL statement, that will
2120: * generate <code>ResultSet</code> objects with the given
2121: * type, concurrency, and holdability
2122: * @exception SQLException if a database access error occurs or
2123: * the given parameters are not <code>ResultSet</code>
2124: * constants indicating type, concurrency, and holdability
2125: * @see ResultSet
2126: * @since JDK 1.4, HSQLDB 1.7.2
2127: */
2128: //#ifdef JDBC3
2129: public synchronized CallableStatement prepareCall(String sql,
2130: int resultSetType, int resultSetConcurrency,
2131: int resultSetHoldability) throws SQLException {
2132:
2133: checkClosed();
2134:
2135: resultSetType = xlateRSType(resultSetType);
2136: resultSetConcurrency = xlateRSConcurrency(resultSetConcurrency);
2137: resultSetHoldability = xlateRSHoldability(resultSetHoldability);
2138:
2139: try {
2140: return new jdbcCallableStatement(this , sql, resultSetType);
2141: } catch (HsqlException e) {
2142: throw Util.sqlException(e);
2143: }
2144: }
2145:
2146: //#endif JDBC3
2147:
2148: /**
2149: * <!-- start generic documentation -->
2150: * Creates a default <code>PreparedStatement</code>
2151: * object that has the capability to retrieve auto-generated
2152: * keys. The given constant tells the driver whether it should
2153: * make auto-generated keys available for retrieval. This
2154: * parameter is ignored if the SQL statement is not an
2155: * <code>INSERT</code> statement. <p>
2156: *
2157: * <B>Note:</B> This method is optimized for handling parametric
2158: * SQL statements that benefit from precompilation. If the driver
2159: * supports precompilation, the method <code>prepareStatement</code>
2160: * will send the statement to the database for precompilation.
2161: * Some drivers may not support precompilation. In this case, the
2162: * statement may not be sent to the database until the
2163: * <code>PreparedStatement</code>
2164: * object is executed. This has no direct effect on users;
2165: * however, it does affect which methods throw certain
2166: * SQLExceptions. <p>
2167: *
2168: * Result sets created using the returned <code>PreparedStatement</code>
2169: * object will by default be type <code>TYPE_FORWARD_ONLY</code>
2170: * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
2171: * <p>
2172: *
2173: * <!-- end generic documentation -->
2174: * <!-- start release-specific documentation -->
2175: * <div class="ReleaseSpecificDocumentation">
2176: * <h3>HSQLDB-Specific Information:</h3> <p>
2177: *
2178: * HSQLDB 1.7.2 does not support this feature. <p>
2179: *
2180: * Calling this method always throws a <code>SQLException</code>,
2181: * stating that the function is not supported. <p>
2182: *
2183: * </div> <!-- end release-specific documentation -->
2184: *
2185: * @param sql an SQL statement that may contain one or more '?'
2186: * IN parameter placeholders
2187: * @param autoGeneratedKeys a flag indicating that auto-generated
2188: * keys should be returned, one of
2189: * code>Statement.RETURN_GENERATED_KEYS</code>
2190: * or <code>Statement.NO_GENERATED_KEYS</code>.
2191: * @return a new <code>PreparedStatement</code> object,
2192: * containing the pre-compiled SQL statement, that will have
2193: * the capability of returning auto-generated keys
2194: * @exception SQLException if a database access error occurs or
2195: * the given parameter is not a <code>Statement</code>
2196: * constant indicating whether auto-generated keys should be
2197: * returned
2198: * @since JDK 1.4, HSQLDB 1.7.2
2199: */
2200: //#ifdef JDBC3
2201: public synchronized PreparedStatement prepareStatement(String sql,
2202: int autoGeneratedKeys) throws SQLException {
2203:
2204: checkClosed();
2205:
2206: throw Util.notSupported();
2207: }
2208:
2209: //#endif JDBC3
2210:
2211: /**
2212: * <!-- start generic documentation -->
2213: * Creates a default <code>PreparedStatement</code>
2214: * object capable of returning the auto-generated keys designated
2215: * by the given array. This array contains the indexes of the
2216: * columns in the target table that contain the auto-generated
2217: * keys that should be made available. This array is ignored if
2218: * the SQL statement is not an <code>INSERT</code> statement. <p>
2219: *
2220: * An SQL statement with or without IN parameters can be
2221: * pre-compiled and stored in a <code>PreparedStatement</code>
2222: * object. This object can then be used to efficiently execute
2223: * this statement multiple times. <p>
2224: *
2225: * <B>Note:</B> This method is optimized for handling parametric
2226: * SQL statements that benefit from precompilation. If the driver
2227: * supports precompilation, the method <code>prepareStatement</code>
2228: * will send the statement to the database for precompilation.
2229: * Some drivers may not support precompilation. In this case, the
2230: * statement may not be sent to the database until the
2231: * <code>PreparedStatement</code>
2232: * object is executed. This has no direct effect on users;
2233: * however, it does affect which methods throw certain
2234: * SQLExceptions. <p>
2235: *
2236: * Result sets created using the returned <code>PreparedStatement</code>
2237: * object will by default be type <code>TYPE_FORWARD_ONLY</code>
2238: * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
2239: * <p>
2240: *
2241: * <!-- end generic documentation -->
2242: * <!-- start release-specific documentation -->
2243: * <div class="ReleaseSpecificDocumentation">
2244: * <h3>HSQLDB-Specific Information:</h3> <p>
2245: *
2246: * HSQLDB 1.7.2 does not support this feature. <p>
2247: *
2248: * Calling this method always throws a <code>SQLException</code>,
2249: * stating that the function is not supported. <p>
2250: *
2251: * </div> <!-- end release-specific documentation -->
2252: *
2253: * @param sql an SQL statement that may contain one or more '?'
2254: * IN parameter placeholders
2255: * @param columnIndexes an array of column indexes indicating the
2256: * columns that should be returned from the inserted row or
2257: * rows
2258: * @return a new <code>PreparedStatement</code> object,
2259: * containing the pre-compiled statement, that is capable of
2260: * returning the auto-generated keys designated by the given
2261: * array of column indexes
2262: * @exception SQLException if a database access error occurs
2263: * @since JDK 1.4, HSQLDB 1.7.2
2264: */
2265: //#ifdef JDBC3
2266: public synchronized PreparedStatement prepareStatement(String sql,
2267: int[] columnIndexes) throws SQLException {
2268:
2269: checkClosed();
2270:
2271: throw Util.notSupported();
2272: }
2273:
2274: //#endif JDBC3
2275:
2276: /**
2277: * <!-- start generic documentation -->
2278: * Creates a default <code>PreparedStatement</code>
2279: * object capable of returning the auto-generated keys designated
2280: * by the given array. This array contains the names of the
2281: * columns in the target table that contain the auto-generated
2282: * keys that should be returned. This array is ignored if the SQL
2283: * statement is not an <code>INSERT</code> statement. <p>
2284: *
2285: * An SQL statement with or without IN parameters can be
2286: * pre-compiled and stored in a <code>PreparedStatement</code>
2287: * object. This object can then be used to efficiently execute
2288: * this statement multiple times. <p>
2289: *
2290: * <B>Note:</B> This method is optimized for handling parametric
2291: * SQL statements that benefit from precompilation. If the driver
2292: * supports precompilation, the method <code>prepareStatement</code>
2293: * will send the statement to the database for precompilation.
2294: * Some drivers may not support precompilation. In this case, the
2295: * statement may not be sent to the database until the
2296: * <code>PreparedStatement</code>
2297: * object is executed. This has no direct effect on users;
2298: * however, it does affect which methods throw certain
2299: * SQLExceptions. <p>
2300: *
2301: * Result sets created using the returned <code>PreparedStatement</code>
2302: * object will by default be type <code>TYPE_FORWARD_ONLY</code>
2303: * and have a concurrency level of <code>CONCUR_READ_ONLY</code>.
2304: * <p>
2305: *
2306: * <!-- end generic documentation -->
2307: * <!-- start release-specific documentation -->
2308: * <div class="ReleaseSpecificDocumentation">
2309: * <h3>HSQLDB-Specific Information:</h3> <p>
2310: *
2311: * HSQLDB 1.7.2 does not support this feature. <p>
2312: *
2313: * Calling this method always throws a <code>SQLException</code>,
2314: * stating that the function is not supported. <p>
2315: *
2316: * </div> <!-- end release-specific documentation -->
2317: *
2318: * @param sql an SQL statement that may contain one or more '?'
2319: * IN parameter placeholders
2320: * @param columnNames an array of column names indicating the
2321: * columns that should be returned from the inserted row or
2322: * rows
2323: * @return a new <code>PreparedStatement</code> object,
2324: * containing the pre-compiled statement, that is capable of
2325: * returning the auto-generated keys designated by the given
2326: * array of column names
2327: * @exception SQLException if a database access error occurs
2328: * @since JDK 1.4, HSQLDB 1.7.2
2329: */
2330: //#ifdef JDBC3
2331: public synchronized PreparedStatement prepareStatement(String sql,
2332: String[] columnNames) throws SQLException {
2333:
2334: checkClosed();
2335:
2336: throw Util.notSupported();
2337: }
2338:
2339: //#endif JDBC3
2340: //---------------------- internal implementation ---------------------------
2341:
2342: /**
2343: * Constructs a new external <code>Connection</code> to an HSQLDB
2344: * <code>Database</code>. <p>
2345: *
2346: * This constructor is called on behalf of the
2347: * <code>java.sql.DriverManager</code> when getting a
2348: * <code>Connection</code> for use in normal (external)
2349: * client code. <p>
2350: *
2351: * Internal client code, that being code located in HSQLDB SQL
2352: * functions and stored procedures, receives an INTERNAL
2353: * connection constructed by the {@link #jdbcConnection(Session)
2354: * jdbcConnection(Session)} constructor. <p>
2355: *
2356: * @param props A <code>Properties</code> object containing the connection
2357: * properties
2358: * @exception SQLException when the user/password combination is
2359: * invalid, the connection url is invalid, or the
2360: * <code>Database</code> is unavailable. <p>
2361: *
2362: * The <code>Database</code> may be unavailable for a number
2363: * of reasons, including network problems or the fact that it
2364: * may already be in use by another process.
2365: */
2366: public jdbcConnection(HsqlProperties props) throws SQLException {
2367:
2368: String user = props.getProperty("user");
2369: String password = props.getProperty("password");
2370: String connType = props.getProperty("connection_type");
2371: String host = props.getProperty("host");
2372: int port = props.getIntegerProperty("port", 0);
2373: String path = props.getProperty("path");
2374: String database = props.getProperty("database");
2375: boolean isTLS = (connType == DatabaseURL.S_HSQLS || connType == DatabaseURL.S_HTTPS);
2376:
2377: if (user == null) {
2378: user = "SA";
2379: }
2380:
2381: if (password == null) {
2382: password = "";
2383: }
2384:
2385: user = user.toUpperCase(Locale.ENGLISH);
2386: password = password.toUpperCase(Locale.ENGLISH);
2387:
2388: try {
2389: if (DatabaseURL.isInProcessDatabaseType(connType)) {
2390:
2391: /** @todo fredt - this should be the only static reference to a core class in
2392: * the jdbc package - we may make it dynamic */
2393: sessionProxy = DatabaseManager.newSession(connType,
2394: database, user, password, props);
2395: } else if (connType == DatabaseURL.S_HSQL
2396: || connType == DatabaseURL.S_HSQLS) {
2397: sessionProxy = new HSQLClientConnection(host, port,
2398: path, database, isTLS, user, password);
2399: isNetConn = true;
2400: } else if (connType == DatabaseURL.S_HTTP
2401: || connType == DatabaseURL.S_HTTPS) {
2402: sessionProxy = new HTTPClientConnection(host, port,
2403: path, database, isTLS, user, password);
2404: isNetConn = true;
2405: } else { // alias: type not yet implemented
2406: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT);
2407: }
2408:
2409: connProperties = props;
2410: } catch (HsqlException e) {
2411: throw Util.sqlException(e);
2412: }
2413: }
2414:
2415: /**
2416: * Constructs an <code>INTERNAL</code> <code>Connection</code>,
2417: * using the specified {@link Session Session}. <p>
2418: *
2419: * This constructor is called only on behalf of an existing
2420: * <code>Session</code> (the internal parallel of a
2421: * <code>Connection</code>), to be used as a parameter to a SQL
2422: * function or stored procedure that needs to execute in the context
2423: * of that <code>Session</code>. <p>
2424: *
2425: * When a Java SQL function or stored procedure is called and its
2426: * first parameter is of type <code>Connection</code>, HSQLDB
2427: * automatically notices this and constructs an <code>INTERNAL</code>
2428: * <code>Connection</code> using the current <code>Session</code>.
2429: * HSQLDB then passes this <code>Connection</code> in the first
2430: * parameter position, moving any other parameter values
2431: * specified in the SQL statement to the right by one position.
2432: * <p>
2433: *
2434: * To read more about this, see {@link Function#getValue()}. <p>
2435: *
2436: * <B>Notes:</B> <p>
2437: *
2438: * Starting with HSQLDB 1.7.2, <code>INTERNAL</code> connections are not
2439: * closed by a call to close() or by a SQL DISCONNECT.
2440: *
2441: * For HSQLDB developers not involved with writing database
2442: * internals, this change only applies to connections obtained
2443: * automatically from the database as the first parameter to
2444: * stored procedures and SQL functions. This is mainly an issue
2445: * to developers writing custom SQL function and stored procedure
2446: * libraries for HSQLDB. Presently, it is recommended that SQL function and
2447: * stored procedure code avoid depending on closing or issuing a
2448: * DISCONNECT on a connection obtained in this manner. <p>
2449: *
2450: * @param c the Session requesting the construction of this
2451: * Connection
2452: * @exception HsqlException never (reserved for future use);
2453: * @see org.hsqldb.Function
2454: */
2455: public jdbcConnection(Session c) throws HsqlException {
2456:
2457: // PRE: Session is non-null
2458: isInternal = true;
2459: sessionProxy = c;
2460: }
2461:
2462: /**
2463: * The default implementation simply attempts to silently {@link
2464: * #close() close()} this <code>Connection</code>
2465: */
2466: protected void finalize() {
2467:
2468: try {
2469: close();
2470: } catch (SQLException e) {
2471: }
2472: }
2473:
2474: /**
2475: * Retrieves this connection's JDBC url.
2476: *
2477: * This method is in support of the jdbcDatabaseMetaData.getURL() method.
2478: *
2479: * @return the database connection url with which this object was
2480: * constructed
2481: */
2482: synchronized String getURL() throws SQLException {
2483:
2484: checkClosed();
2485:
2486: if (isInternal) {
2487: return ((Session) sessionProxy).getInternalConnectionURL();
2488: }
2489:
2490: return connProperties.getProperty("url");
2491: }
2492:
2493: /**
2494: * An internal check for closed connections. <p>
2495: *
2496: * @throws SQLException when the connection is closed
2497: */
2498: synchronized void checkClosed() throws SQLException {
2499:
2500: if (isClosed) {
2501: throw Util.sqlException(Trace.CONNECTION_IS_CLOSED);
2502: }
2503: }
2504:
2505: /**
2506: * Adds another SQLWarning to this Connection object's warning chain.
2507: *
2508: * @param w the SQLWarning to add to the chain
2509: */
2510: void addWarning(SQLWarning w) {
2511:
2512: // PRE: w is never null
2513: synchronized (rootWarning_mutex) {
2514: if (rootWarning == null) {
2515: rootWarning = w;
2516: } else {
2517: rootWarning.setNextWarning(w);
2518: }
2519: }
2520: }
2521:
2522: /**
2523: * Clears the warning chain without checking if this Connection is closed.
2524: */
2525: void clearWarningsNoCheck() {
2526:
2527: synchronized (rootWarning_mutex) {
2528: rootWarning = null;
2529: }
2530: }
2531:
2532: /**
2533: * Translates <code>ResultSet</code> type, adding to the warning
2534: * chain if the requested type is downgraded. <p>
2535: *
2536: * Up to and including HSQLDB 1.7.2, <code>TYPE_FORWARD_ONLY</code> and
2537: * <code>TYPE_SCROLL_INSENSITIVE</code> are passed through. <p>
2538: *
2539: * Starting with 1.7.2, while <code>TYPE_SCROLL_SENSITIVE</code> is
2540: * downgraded to <code>TYPE_SCROLL_INSENSITIVE</code> and an SQLWarning is
2541: * issued. <p>
2542: *
2543: * @param type of <code>ResultSet</code>; one of
2544: * <code>jdbcResultSet.TYPE_XXX</code>
2545: * @return the actual type that will be used
2546: * @throws SQLException if type is not one of the defined values
2547: */
2548: int xlateRSType(int type) throws SQLException {
2549:
2550: SQLWarning w;
2551: String msg;
2552:
2553: switch (type) {
2554:
2555: case jdbcResultSet.TYPE_FORWARD_ONLY:
2556: case jdbcResultSet.TYPE_SCROLL_INSENSITIVE: {
2557: return type;
2558: }
2559: case jdbcResultSet.TYPE_SCROLL_SENSITIVE: {
2560: msg = "TYPE_SCROLL_SENSITIVE => TYPE_SCROLL_SENSITIVE";
2561: w = new SQLWarning(msg, "SOO10",
2562: Trace.INVALID_JDBC_ARGUMENT);
2563:
2564: addWarning(w);
2565:
2566: return jdbcResultSet.TYPE_SCROLL_INSENSITIVE;
2567: }
2568: default: {
2569: msg = "ResultSet type: " + type;
2570:
2571: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
2572: }
2573: }
2574: }
2575:
2576: /**
2577: * Translates <code>ResultSet</code> concurrency, adding to the warning
2578: * chain if the requested concurrency is downgraded. <p>
2579: *
2580: * Starting with HSQLDB 1.7.2, <code>CONCUR_READ_ONLY</code> is
2581: * passed through while <code>CONCUR_UPDATABLE</code> is downgraded
2582: * to <code>CONCUR_READ_ONLY</code> and an SQLWarning is issued.
2583: *
2584: * @param concurrency of <code>ResultSet</code>; one of
2585: * <code>jdbcResultSet.CONCUR_XXX</code>
2586: * @return the actual concurrency that will be used
2587: * @throws SQLException if concurrency is not one of the defined values
2588: */
2589: int xlateRSConcurrency(int concurrency) throws SQLException {
2590:
2591: SQLWarning w;
2592: String msg;
2593:
2594: switch (concurrency) {
2595:
2596: case jdbcResultSet.CONCUR_READ_ONLY: {
2597: return concurrency;
2598: }
2599: case jdbcResultSet.CONCUR_UPDATABLE: {
2600: msg = "CONCUR_UPDATABLE => CONCUR_READ_ONLY";
2601: w = new SQLWarning(msg, "SOO10",
2602: Trace.INVALID_JDBC_ARGUMENT);
2603:
2604: addWarning(w);
2605:
2606: return jdbcResultSet.CONCUR_READ_ONLY;
2607: }
2608: default: {
2609: msg = "ResultSet concurrency: " + concurrency;
2610:
2611: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
2612: }
2613: }
2614: }
2615:
2616: /**
2617: * Translates <code>ResultSet</code> holdability, adding to the warning
2618: * chain if the requested holdability is changed from an unsupported to
2619: * a supported value. <p>
2620: *
2621: * Starting with HSQLDB 1.7.2, <code>HOLD_CURSORS_OVER_COMMIT</code> is
2622: * passed through while <code>CLOSE_CURSORS_AT_COMMIT</code> is changed
2623: * to <code>HOLD_CURSORS_OVER_COMMIT</code> and an SQLWarning is
2624: * issued. <p>
2625: *
2626: * @param holdability of <code>ResultSet</code>; one of
2627: * <code>jdbcResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
2628: * <code>jdbcResultSet.CLOSE_CURSORS_AT_COMMIT</code>
2629: * @return the actual holdability that will be used
2630: * @throws SQLException if holdability is not one of the defined values
2631: */
2632: int xlateRSHoldability(int holdability) throws SQLException {
2633:
2634: SQLWarning w;
2635: String msg;
2636:
2637: switch (holdability) {
2638:
2639: case jdbcResultSet.HOLD_CURSORS_OVER_COMMIT: {
2640: return holdability;
2641: }
2642: case jdbcResultSet.CLOSE_CURSORS_AT_COMMIT: {
2643: msg = "CLOSE_CURSORS_AT_COMMIT => HOLD_CURSORS_OVER_COMMIT";
2644: w = new SQLWarning(msg, "SOO10",
2645: Trace.INVALID_JDBC_ARGUMENT);
2646:
2647: addWarning(w);
2648:
2649: return jdbcResultSet.HOLD_CURSORS_OVER_COMMIT;
2650: }
2651: default: {
2652: msg = "ResultSet holdability: " + holdability;
2653:
2654: throw Util.sqlException(Trace.INVALID_JDBC_ARGUMENT, msg);
2655: }
2656: }
2657: }
2658:
2659: /**
2660: * Resets this connection so it can be used again. Used when connections are
2661: * returned to a connection pool.
2662: */
2663: public void reset() throws SQLException {
2664:
2665: try {
2666: this .sessionProxy.resetSession();
2667: } catch (HsqlException e) {
2668: throw new SQLException("Error resetting connection: "
2669: + e.getMessage());
2670: }
2671: }
2672:
2673: /**
2674: * is called from within nativeSQL when the start of an JDBC escape sequence is encountered
2675: */
2676: private int onStartEscapeSequence(String sql, StringBuffer sb, int i)
2677: throws SQLException {
2678:
2679: sb.setCharAt(i++, ' ');
2680:
2681: i = StringUtil.skipSpaces(sql, i);
2682:
2683: if (sql.regionMatches(true, i, "fn ", 0, 3)
2684: || sql.regionMatches(true, i, "oj ", 0, 3)
2685: || sql.regionMatches(true, i, "ts ", 0, 3)) {
2686: sb.setCharAt(i++, ' ');
2687: sb.setCharAt(i++, ' ');
2688: } else if (sql.regionMatches(true, i, "d ", 0, 2)
2689: || sql.regionMatches(true, i, "t ", 0, 2)) {
2690: sb.setCharAt(i++, ' ');
2691: } else if (sql.regionMatches(true, i, "call ", 0, 5)) {
2692: i += 4;
2693: } else if (sql.regionMatches(true, i, "?= call ", 0, 8)) {
2694: sb.setCharAt(i++, ' ');
2695: sb.setCharAt(i++, ' ');
2696:
2697: i += 5;
2698: } else if (sql.regionMatches(true, i, "escape ", 0, 7)) {
2699: i += 6;
2700: } else {
2701: i--;
2702:
2703: throw new SQLException(Trace.getMessage(
2704: Trace.jdbcConnection_nativeSQL, true,
2705: new Object[] { sql.substring(i) }), "S0010",
2706: Trace.INVALID_JDBC_ARGUMENT);
2707: }
2708:
2709: return i;
2710: }
2711: }
|