org.hsqldb.jdbc.JDBCConnection Maven / Gradle / Ivy
Show all versions of sqltool Show documentation
/* Copyright (c) 2001-2021, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb.jdbc;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLFeatureNotSupportedException;
//import java.sql.SQLData;
//import java.sql.SQLOutput;
//import java.sql.SQLInput;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Calendar;
import java.util.Map;
import java.util.Properties;
// import java.util.logging.Level;
// import java.util.logging.Logger;
import org.hsqldb.ClientConnection;
import org.hsqldb.ClientConnectionHTTP;
import org.hsqldb.DatabaseManager;
import org.hsqldb.DatabaseURL;
import org.hsqldb.HsqlDateTime;
import org.hsqldb.HsqlException;
import org.hsqldb.SessionInterface;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.StringUtil;
import org.hsqldb.persist.HsqlDatabaseProperties;
import org.hsqldb.persist.HsqlProperties;
import org.hsqldb.result.Result;
import org.hsqldb.result.ResultConstants;
import org.hsqldb.result.ResultProperties;
import org.hsqldb.types.ArrayType;
import org.hsqldb.types.Type;
/* $Id: JDBCConnection.java 6294 2021-02-07 18:08:27Z fredt $ */
// fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
//
// campbell-burnet@users 20020509 - added "throws SQLException" to all methods where
// it was missing here but specified in the
// java.sql.Connection interface,
// updated generic documentation to JDK 1.4, and
// added JDBC3 methods and docs
// boucherb &
// fredt@users 20020505 - extensive review and update of docs and behaviour
// to comply with java.sql specification
// fredt@users 20020830 - patch 487323 by xclayl@users - better synchronization
// fredt@users 20020930 - patch 1.7.1 - support for connection properties
// kneedeepincode@users
// 20021110 - patch 635816 - correction to properties
// unsaved@users 20021113 - patch 1.7.2 - SSL support
// campbell-burnet@users 2003 ??? - patch 1.7.2 - SSL support moved to factory interface
// fredt@users 20030620 - patch 1.7.2 - reworked to use a SessionInterface
// campbell-burnet@users 20030801 - JavaDoc updates to reflect new connection urls
// campbell-burnet@users 20030819 - patch 1.7.2 - partial fix for broken nativeSQL method
// campbell-burnet@users 20030819 - patch 1.7.2 - SQLWarning cases implemented
// campbell-burnet@users 20051207 - 1.9.0 - JDBC 4.0 support - docs and methods
// - 20060712 - full synch up to Mustang Build 90
// fredt@users 20090810 - 1.9.0 - full review and updates
//
// Revision 1.23 2006/07/12 12:02:43 boucherb
// patch 1.9.0
// - full synch up to Mustang b90
/**
*
*
* A connection (session) with a specific
* database. SQL statements are executed and results are returned
* within the context of a connection.
*
* A Connection
object's database is able to provide information
* describing its tables, its supported SQL grammar, its stored
* procedures, the capabilities of this connection, and so on. This
* information is obtained with the getMetaData
method.
*
*
(JDBC4 clarification:)
*
Note: When configuring a Connection
, JDBC applications
* should use the appropriate Connection
method such as
* setAutoCommit
or setTransactionIsolation
.
* Applications should not invoke SQL commands directly to change the connection's
* configuration when there is a JDBC method available. By default a Connection
object is in
* auto-commit mode, which means that it automatically commits changes
* after executing each statement. If auto-commit mode has been
* disabled, the method commit
must be called explicitly in
* order to commit changes; otherwise, database changes will not be saved.
*
* A new Connection
object created using the JDBC 2.1 core API
* has an initially empty type map associated with it. A user may enter a
* custom mapping for a UDT in this type map.
* When a UDT is retrieved from a data source with the
* method ResultSet.getObject
, the getObject
method
* will check the connection's type map to see if there is an entry for that
* UDT. If so, the getObject
method will map the UDT to the
* class indicated. If there is no entry, the UDT will be mapped using the
* standard mapping.
*
* A user may create a new type map, which is a java.util.Map
* object, make an entry in it, and pass it to the java.sql
* methods that can perform custom mapping. In this case, the method
* will use the given type map instead of the one associated with
* the connection.
*
* For example, the following code fragment specifies that the SQL
* type ATHLETES
will be mapped to the class
* Athletes
in the Java programming language.
* The code fragment retrieves the type map for the Connection
*
object con
, inserts the entry into it, and then sets
* the type map with the new entry as the connection's type map.
*
* java.util.Map map = con.getTypeMap();
* map.put("mySchemaName.ATHLETES", Class.forName("Athletes"));
* con.setTypeMap(map);
*
*
*
*
*
*
* HSQLDB-Specific Information:
*
* To get a Connection
to an HSQLDB database, the
* following code may be used (updated to reflect the most recent
* recommendations):
*
*
*
* When using HSQLDB, the database connection <url> must start with
* 'jdbc:hsqldb:'
*
* Since 1.7.2, connection properties (<key-value-pairs>) may be appended
* to the database connection <url>, using the form:
*
*
* '<url>[;key=value]*'
*
*
* Also since 1.7.2, the allowable forms of the HSQLDB database connection
* <url> have been extended. However, all legacy forms continue
* to work, with unchanged semantics. The extensions are as described in the
* following material.
*
*
*
* Network Server Database Connections:
*
* The {@link org.hsqldb.server.Server Server} database connection <url>
* takes one of the two following forms:
*
*
*
* - 'jdbc:hsqldb:hsql://host[:port][/<alias>][<key-value-pairs>]'
*
*
- 'jdbc:hsqldb:hsqls://host[:port][/<alias>][<key-value-pairs>]'
* (with TLS).
*
*
*
* The {@link org.hsqldb.server.WebServer WebServer} database connection <url>
* takes one of two following forms:
*
*
*
* - 'jdbc:hsqldb:http://host[:port][/<alias>][<key-value-pairs>]'
*
*
- 'jdbc:hsqldb:https://host[:port][/<alias>][<key-value-pairs>]'
* (with TLS).
*
*
*
* In both network server database connection <url> forms, the
* optional <alias> component is used to identify one of possibly
* several database instances available at the indicated host and port. If the
* <alias> component is omitted, then a connection is made to the
* network server's default database instance, if such an instance is
* available.
*
* For more information on server configuration regarding mounting multiple
* databases and assigning them <alias> values, please read the
* Java API documentation for {@link org.hsqldb.server.Server Server} and related
* chapters in the general documentation, especially the Advanced Users
* Guide.
*
*
*
* Transient, In-Process Database Connections:
*
* The 100% in-memory (transient, in-process) database connection
* <url> takes one of the two following forms:
*
*
*
* - 'jdbc:hsqldb:.[<key-value-pairs>]'
* (the legacy form, extended)
*
*
- 'jdbc:hsqldb:mem:<alias>[<key-value-pairs>]'
* (the new form)
*
*
*
* The driver converts the supplied <alias> component to
* Local.ENGLISH lower case and uses the resulting character sequence as the
* key used to look up a mem: protocol database instance amongst the
* collection of all such instances already in existence within the current
* class loading context in the current JVM. If no such instance exists, one
* may be automatically created and mapped to the <alias>,
* as governed by the 'ifexists=true|false' connection property.
*
* The rationale for converting the supplied <alias> component to
* lower case is to provide consistency with the behavior of res:
* protocol database connection <url>s, explained further on in
* this overview.
*
*
*
* Persistent, In-Process Database Connections:
*
* The standalone (persistent, in-process) database connection
* <url> takes one of the three following forms:
*
*
*
* - 'jdbc:hsqldb:<path>[<key-value-pairs>]'
* (the legacy form, extended)
*
*
- 'jdbc:hsqldb:file:<path>[<key-value-pairs>]'
* (same semantics as the legacy form)
*
*
- 'jdbc:hsqldb:res:<path>[<key-value-pairs>]'
* (new form with 'files_in_jar' semantics)
*
*
*
* For the persistent, in-process database connection <url>,
* the <path> component is the path prefix common to all of
* the files that compose the database.
*
* From 1.7.2, although other files may be involved (such as transient working
* files and/or TEXT table CSV data source files), the essential set that may,
* at any particular point in time, compose an HSQLDB database is:
*
*
*
* - <path>.properties
*
- <path>.script
*
- <path>.log
*
- <path>.data
*
- <path>.backup
*
- <path>.lck
*
*
*
* For example: 'jdbc:hsqldb:file:test' connects to a database
* composed of some subset of the files listed above, where the expansion
* of <path> is 'test' prefixed with the canonical path of
* the JVM's effective working directory at the time the designated database
* is first opened in-process.
*
* Be careful to note that this canonical expansion of <path> is
* cached by the driver until JVM exit. So, although legacy JVMs tend to fix
* the reported effective working directory at the one noted upon JVM startup,
* there is no guarantee that modern JVMs will continue to uphold this
* behaviour. What this means is there is effectively no guarantee into the
* future that a relative file: protocol database connection
* <url> will connect to the same database instance for the life
* of the JVM. To avoid any future ambiguity issues, it is probably a best
* practice for clients to attempt to pre-canonicalize the <path>
* component of file: protocol database connection* <url>s.
*
*
* Under Windows,
* 'jdbc:hsqldb:file:c:\databases\test' connects to a database located
* on drive 'C:' in the directory 'databases', composed
* of some subset of the files:
*
*
* C:\
* +--databases\
* +--test.properties
* +--test.script
* +--test.log
* +--test.data
* +--test.backup
* +--test.lck
*
*
* Under most variations of UNIX, 'jdbc:hsqldb:file:/databases/test'
* connects to a database located in the directory 'databases' directly
* under root, once again composed of some subset of the files:
*
*
*
* +--databases
* +--test.properties
* +--test.script
* +--test.log
* +--test.data
* +--test.backup
* +--test.lck
*
*
* Some Guidelines:
*
*
* - Both relative and absolute database file paths are supported.
*
*
- Relative database file paths can be specified in a platform independent
* manner as: '[dir1/dir2/.../dirn/]<file-name-prefix>'.
*
*
- Specification of absolute file paths is operating-system specific.
* Please read your OS file system documentation.
*
* - Specification of network mounts may be operating-system specific.
* Please read your OS file system documentation.
*
* - Special care may be needed w.r.t. file path specifications
* containing whitespace, mixed-case, special characters and/or
* reserved file names.
* Please read your OS file system documentation.
*
*
* Note: Versions of HSQLDB previous to 1.7.0 did not support creating
* directories along the file path specified in the persistent, in-process mode
* database connection <url> form, in the case that they did
* not already exist. Starting with HSQLDB 1.7.0, directories will
* be created if they do not already exist., but only if HSQLDB is built under
* a version of the compiler greater than JDK 1.1.x.
*
*
*
* res: protocol Connections:
*
* The 'jdbc:hsqldb:res:<path>' database connection
* <url> has different semantics than the
* 'jdbc:hsqldb:file:<path>' form. The semantics are similar to
* those of a 'files_readonly' database, but with some additional
* points to consider.
*
* Specifically, the '<path>' component of a res: protocol
* database connection <url> is first converted to lower case
* with Locale.ENGLISH
and only then used to obtain resource URL
* objects, which in turn are used to read the database files as resources on
* the class path.
*
* Due to lower case conversion by the driver, res: '<path>'
* components never find jar resources stored with
* Locale.ENGLISH
mixed case paths. The rationale for converting to
* lower case is that not all pkzip implementations guarantee path case is
* preserved when archiving resources, and conversion to lower case seems to
* be the most common occurrence (although there is also no actual guarantee
* that the conversion is Locale.ENGLISH
).
*
* More importantly, res: '<path>' components must
* point only to resources contained in one or more jars on the class
* path. That is, only resources having the jar sub-protocol are considered
* valid.
*
* This restriction is enforced to avoid the unfortunate situation in which,
* because res: database instances do not create a <path>.lck
* file (they are strictly files-read-only) and because the <path>
* components of res: and file: database URI
s are not
* checked for file system equivalence, it is possible for the same database
* files to be accessed concurrently by both file: and res:
* database instances. That is, without this restriction, it is possible that
* <path>.data and <path>.properties file content may
* be written by a file: database instance without the knowledge or
* cooperation of a res: database instance open on the same files,
* potentially resulting in unexpected database errors, inconsistent operation
* and/or data corruption.
*
* In short, a res: type database connection <url> is
* designed specifically to connect to a 'files_in_jar' mode database
* instance, which in turn is designed specifically to operate under
* Java WebStart and
* Java Applet configurations,
* where co-locating the database files in the jars that make up the
* WebStart application or Applet avoids the need for special security
* configuration or code signing.
*
* Note: Since it is difficult and often nearly impossible to determine
* or control at runtime from where all classes are being loaded or which class
* loader is doing the loading (and hence how relative path specifications
* are resolved) under 'files_in_jar' semantics, the <path>
* component of the res: database connection <url> is always
* taken to be relative to the default package and resource URL resolution is
* always performed using the ClassLoader that loads the
* org.hsqldb.persist.Logger class. That is, if the <path>
* component does not start with '/', then'/' is prepended when obtaining the
* resource URLs used to read the database files, and only the effective class
* path of org.hsqldb.persist.Logger's ClassLoader is searched.
*
*
*
* For more information about HSQLDB file structure, various database modes
* and other attributes such as those controlled through the HSQLDB properties
* files, please read the general documentation, especially the Advanced Users
* Guide.
*
* JDBC 4.0 Notes:
*
* Starting with JDBC 4.0 (JDK 1.6), the DriverManager
methods
* getConnection
and getDrivers
have been
* enhanced to support the Java Standard Edition Service Provider mechanism.
* When built under a Java runtime that supports JDBC 4.0, HSQLDB distribution
* jars containing the Driver implementation also include the file
* META-INF/services/java.sql.Driver
. This file contains the fully
* qualified class name ('org.hsqldb.jdbc.JDBCDriver') of the HSQLDB implementation
* of java.sql.Driver
.
*
* Hence, under JDBC 4.0 or greater, applications no longer need to explicitly
* load the HSQLDB JDBC driver using Class.forName()
. Of course,
* existing programs which do load JDBC drivers using
* Class.forName()
will continue to work without modification.
*
*
*
* (fredt@users)
* (campbell-burnet@users)
*
*
* @author Campbell Burnet (campbell-burnet@users dot sourceforge.net)
* @author Fred Toussi (fredt@users dot sourceforge.net)
* @version 2.6.0
* @since HSQLDB 1.9.0
* @see JDBCDriver
* @see JDBCStatement
* @see JDBCParameterMetaData
* @see JDBCCallableStatement
* @see JDBCResultSet
* @see JDBCDatabaseMetaData
* @see java.sql.DriverManager
* @see java.sql.Statement
* @see java.sql.ResultSet
* @see java.sql.DatabaseMetaData
*/
public class JDBCConnection implements Connection {
// ----------------------------------- JDBC 1 -------------------------------
/**
*
*
* Creates a Statement
object for sending
* SQL statements to the database.
* SQL statements without parameters are normally
* executed using Statement
objects. If the same SQL statement
* is executed many times, it may be more efficient to use a
* PreparedStatement
object.
*
* Result sets created using the returned Statement
* object will by default be type TYPE_FORWARD_ONLY
* and have a concurrency level of CONCUR_READ_ONLY
.
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with HSQLDB 1.7.2, support for precompilation at the engine level
* has been implemented, so it is now much more efficient and performant
* to use a PreparedStatement
object if the same short-running
* SQL statement is to be executed many times.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
and CONCUR_READ_ONLY
* results.
*
*
*
* @return a new default Statement
object
* @exception SQLException if a database access error occurs
* (JDBC4 clarification:)
* or this method is called on a closed connection
* @see #createStatement(int,int)
* @see #createStatement(int,int,int)
*/
public synchronized Statement createStatement() throws SQLException {
checkClosed();
int props =
ResultProperties.getValueForJDBC(JDBCResultSet.TYPE_FORWARD_ONLY,
JDBCResultSet.CONCUR_READ_ONLY, rsHoldability);
Statement stmt = new JDBCStatement(this, props);
return stmt;
}
/**
*
*
* Creates a PreparedStatement
object for sending
* parameterized SQL statements to the database.
*
* A SQL statement with or without IN parameters can be
* pre-compiled and stored in a PreparedStatement
object. This
* object can then be used to efficiently execute this statement
* multiple times.
*
*
Note: This method is optimized for handling
* parametric SQL statements that benefit from precompilation. If
* the driver supports precompilation,
* the method prepareStatement
will send
* the statement to the database for precompilation. Some drivers
* may not support precompilation. In this case, the statement may
* not be sent to the database until the PreparedStatement
* object is executed. This has no direct effect on users; however, it does
* affect which methods throw certain SQLException
objects.
*
* Result sets created using the returned PreparedStatement
* object will by default be type TYPE_FORWARD_ONLY
* and have a concurrency level of CONCUR_READ_ONLY
.
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with HSQLDB 1.7.2, support for precompilation at the engine level
* has been implemented, so it is now much more efficient and performant
* to use a PreparedStatement
object if the same short-running
* SQL statement is to be executed many times.
*
* The support for and behaviour of PreparedStatement complies with SQL and
* JDBC standards. Please read the introductory section
* of the documentation for ${link JDBCParameterMetaData}.
*
*
*
* @param sql an SQL statement that may contain one or more '?' IN
* parameter placeholders
* @return a new default PreparedStatement
object containing the
* pre-compiled SQL statement
* @exception SQLException if a database access error occurs
* (JDBC4 clarification:)
* or this method is called on a closed connection
* @see #prepareStatement(String,int,int)
*/
public synchronized PreparedStatement prepareStatement(
String sql) throws SQLException {
checkClosed();
try {
return new JDBCPreparedStatement(this, sql,
JDBCResultSet.TYPE_FORWARD_ONLY,
JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Creates a CallableStatement
object for calling
* database stored procedures.
* The CallableStatement
object provides
* methods for setting up its IN and OUT parameters, and
* methods for executing the call to a stored procedure.
*
* Note: This method is optimized for handling stored
* procedure call statements. Some drivers may send the call
* statement to the database when the method prepareCall
* is done; others
* may wait until the CallableStatement
object
* is executed. This has no
* direct effect on users; however, it does affect which method
* throws certain SQLExceptions.
*
* Result sets created using the returned CallableStatement
* object will by default be type TYPE_FORWARD_ONLY
* and have a concurrency level of CONCUR_READ_ONLY
.
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with 1.7.2, the support for and behaviour of
* CallableStatement has changed. Please read the introductory section
* of the documentation for org.hsqldb.jdbc.JDBCCallableStatement.
*
*
*
* @param sql an SQL statement that may contain one or more '?'
* parameter placeholders. (JDBC4 clarification:) Typically this statement is specified using JDBC
* call escape syntax.
* @return a new default CallableStatement
object containing the
* pre-compiled SQL statement
* @exception SQLException if a database access error occurs
* (JDBC4 clarification:)
* or this method is called on a closed connection
* @see #prepareCall(String,int,int)
*/
public synchronized CallableStatement prepareCall(
String sql) throws SQLException {
CallableStatement stmt;
checkClosed();
try {
stmt = new JDBCCallableStatement(this, sql,
JDBCResultSet.TYPE_FORWARD_ONLY,
JDBCResultSet.CONCUR_READ_ONLY, rsHoldability);
return stmt;
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Converts the given SQL statement into the system's native SQL grammar.
* A driver may convert the JDBC SQL grammar into its system's
* native SQL grammar prior to sending it. This method returns the
* native form of the statement that the driver would have sent.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB converts the JDBC SQL
* grammar into the system's native SQL grammar prior to sending
* it, if escape processing is set true; this method returns the
* native form of the statement that the driver would send in place
* of client-specified JDBC SQL grammar.
*
* Before 1.7.2, escape processing was incomplete and
* also broken in terms of support for nested escapes.
*
* Starting with 1.7.2, escape processing is complete and handles nesting
* to arbitrary depth, but enforces a very strict interpretation of the
* syntax and does not detect or process SQL comments.
*
* In essence, the HSQLDB engine directly handles the prescribed syntax
* and date / time formats specified internal to the JDBC escapes.
* It also directly offers the XOpen / ODBC extended scalar
* functions specified available internal to the {fn ...} JDBC escape.
* As such, the driver simply removes the curly braces and JDBC escape
* codes in the simplest and fastest fashion possible, by replacing them
* with whitespace.
*
* But to avoid a great deal of complexity, certain forms of input
* whitespace are currently not recognised. For instance,
* the driver handles "{?= call ...}" but not "{ ?= call ...} or
* "{? = call ...}"
*
* Also, comments embedded in SQL are currently not detected or
* processed and thus may have unexpected effects on the output
* of this method, for instance causing otherwise valid SQL to become
* invalid. It is especially important to be aware of this because escape
* processing is set true by default for Statement objects and is always
* set true when producing a PreparedStatement from prepareStatement()
* or CallableStatement from prepareCall(). Currently, it is simply
* recommended to avoid submitting SQL having comments containing JDBC
* escape sequence patterns and/or single or double quotation marks,
* as this will avoid any potential problems.
*
* It is intended to implement a less strict handling of whitespace and
* proper processing of SQL comments at some point in the near future.
*
* In any event, 1.7.2 now correctly processes the following JDBC escape
* forms to arbitrary nesting depth, but only if the exact whitespace
* layout described below is used:
*
*
* - {call ...}
*
- {?= call ...}
*
- {fn ...}
*
- {oj ...}
*
- {d ...}
*
- {t ...}
*
- {ts ...}
*
*
*
*
* @param sql an SQL statement that may contain one or more '?'
* parameter placeholders
* @return the native form of this statement
* @exception SQLException if a database access error occurs
* (JDBC4 clarification:)
* or this method is called on a closed connection
*/
public synchronized String nativeSQL(
final String sql) throws SQLException {
checkClosed();
if (sql == null || sql.isEmpty() || sql.indexOf('{') == -1) {
return sql;
}
boolean changed = false;
int state = 0;
int len = sql.length();
int nest = 0;
StringBuilder sb = null;
String msg;
//--
final int outside_all = 0;
final int outside_escape_inside_single_quotes = 1;
final int outside_escape_inside_double_quotes = 2;
//--
final int inside_escape = 3;
final int inside_escape_inside_single_quotes = 4;
final int inside_escape_inside_double_quotes = 5;
/* @todo */
// final int inside_single_line_comment = 6;
// final int inside_multi_line_comment = 7;
// Better than old way for large inputs and for avoiding GC overhead;
// toString() reuses internal char[], reducing memory requirement
// and garbage items 3:2
int tail = 0;
for (int i = 0; i < len; i++) {
char c = sql.charAt(i);
switch (state) {
case outside_all : // Not inside an escape or quotes
if (c == '\'') {
state = outside_escape_inside_single_quotes;
} else if (c == '"') {
state = outside_escape_inside_double_quotes;
} else if (c == '{') {
if (sb == null) {
sb = new StringBuilder(sql.length());
}
sb.append(sql, tail, i);
i = onStartEscapeSequence(sql, sb, i);
tail = i;
changed = true;
nest++;
state = inside_escape;
}
break;
case outside_escape_inside_single_quotes : // inside ' ' only
case inside_escape_inside_single_quotes : // inside { } and ' '
if (c == '\'') {
state -= 1;
}
break;
case outside_escape_inside_double_quotes : // inside " " only
case inside_escape_inside_double_quotes : // inside { } and " "
if (c == '"') {
state -= 2;
}
break;
case inside_escape : // inside { }
if (c == '\'') {
state = inside_escape_inside_single_quotes;
} else if (c == '"') {
state = inside_escape_inside_double_quotes;
} else if (c == '}') {
sb.append(sql, tail, i);
sb.append(' ');
i++;
tail = i;
changed = true;
nest--;
state = (nest == 0) ? outside_all
: inside_escape;
} else if (c == '{') {
sb.append(sql, tail, i);
i = onStartEscapeSequence(sql, sb, i);
tail = i;
changed = true;
nest++;
state = inside_escape;
}
break;
default:
}
}
if (!changed) {
return sql;
}
sb.append(sql.substring(tail));
return sb.toString();
}
/*
* @todo - semantics of autocommit regarding commit when the ResultSet is closed
*/
/**
*
*
* Sets this connection's auto-commit mode to the given state.
* If a connection is in auto-commit mode, then all its SQL
* statements will be executed and committed as individual
* transactions. Otherwise, its SQL statements are grouped into
* transactions that are terminated by a call to either
* the method commit
or the method rollback
.
* By default, new connections are in auto-commit
* mode.
*
* The commit occurs when the statement completes. The time when the statement
* completes depends on the type of SQL Statement:
*
* - For DML statements, such as Insert, Update or Delete, and DDL statements,
* the statement is complete as soon as it has finished executing.
*
- For Select statements, the statement is complete when the associated result
* set is closed.
*
- For
CallableStatement
objects or for statements that return
* multiple results, the statement is complete
* when all of the associated result sets have been closed, and all update
* counts and output parameters have been retrieved.
*
*
* NOTE: If this method is called during a transaction and the
* auto-commit mode is changed, the transaction is committed. If
* setAutoCommit
is called and the auto-commit mode is
* not changed, the call is a no-op.
*
*
*
*
* HSQLDB-Specific Information:
*
* Up to and including HSQLDB 2.0,
*
*
* - All rows of a result set are retrieved internally
* before the first row can actually be fetched.
* Therefore, a statement can be considered complete as soon as
* any XXXStatement.executeXXX method returns.
*
*
*
* Starting with 2.0, HSQLDB may not return a result set to the network
* client as a whole; the generic documentation will apply. The fetch
* size is taken into account
*
* (campbell-burnet@users)
*
* @param autoCommit true
to enable auto-commit mode;
* false
to disable it
* @exception SQLException if a database access error occurs,
* (JDBC4 Clarification:)
* setAutoCommit(true) is called while participating in a distributed transaction,
* or this method is called on a closed connection
* @see #getAutoCommit
*/
public synchronized void setAutoCommit(
boolean autoCommit) throws SQLException {
checkClosed();
try {
sessionProxy.setAutoCommit(autoCommit);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
* Retrieves the current auto-commit mode for this Connection
* object.
*
* @return the current state of this Connection
object's
* auto-commit mode
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @see #setAutoCommit
*/
public synchronized boolean getAutoCommit() throws SQLException {
checkClosed();
try {
return sessionProxy.isAutoCommit();
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Makes all changes made since the previous
* commit/rollback permanent and releases any database locks
* currently held by this Connection
object.
* This method should be
* used only when auto-commit mode has been disabled.
*
*
*
*
* HSQLDB-Specific Information:
*
*
* @exception SQLException if a database access error occurs,
* (JDBC4 Clarification:)
* this method is called while participating in a distributed transaction,
* if this method is called on a closed connection or this
* Connection
object is in auto-commit mode
* @see #setAutoCommit
*/
public synchronized void commit() throws SQLException {
checkClosed();
try {
sessionProxy.commit(false);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Undoes all changes made in the current transaction
* and releases any database locks currently held
* by this Connection
object. This method should be
* used only when auto-commit mode has been disabled.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with HSQLDB 1.7.2, savepoints are fully supported both
* in SQL and via the JDBC interface.
*
* Using SQL, savepoints may be set, released and used in rollback
* as follows:
*
*
* SAVEPOINT <savepoint-name>
* RELEASE SAVEPOINT <savepoint-name>
* ROLLBACK TO SAVEPOINT <savepoint-name>
*
*
*
*
* @exception SQLException if a database access error occurs,
* (JDBC4 Clarification:)
* this method is called while participating in a distributed transaction,
* this method is called on a closed connection or this
* Connection
object is in auto-commit mode
* @see #setAutoCommit
*/
public synchronized void rollback() throws SQLException {
checkClosed();
try {
sessionProxy.rollback(false);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Releases this Connection
object's database and JDBC resources
* immediately instead of waiting for them to be automatically released.
*
* Calling the method close
on a Connection
* object that is already closed is a no-op.
*
* It is strongly recommended that an application explicitly
* commits or rolls back an active transaction prior to calling the
* close
method. If the close
method is called
* and there is an active transaction, the results are implementation-defined.
*
*
*
*
* HSQLDB-Specific Information:
*
* From 1.7.2, HSQLDB INTERNAL
Connection
* objects are not closable from JDBC client code.
*
*
*
* @exception SQLException SQLException if a database access error occurs
*/
public synchronized void close() throws SQLException {
// Changed to synchronized above because
// we would not want a sessionProxy.close()
// operation to occur concurrently with a
// statementXXX.executeXXX operation.
if (isInternal || isClosed) {
return;
}
isClosed = true;
rootWarning = null;
connProperties = null;
if (isPooled) {
if (poolEventListener != null) {
poolEventListener.connectionClosed();
poolEventListener = null;
}
} else if (sessionProxy != null) {
sessionProxy.close();
sessionProxy = null;
}
}
/**
* Retrieves whether this Connection
object has been
* closed. A connection is closed if the method close
* has been called on it or if certain fatal errors have occurred.
* This method is guaranteed to return true
only when
* it is called after the method Connection.close
has
* been called.
*
* This method generally cannot be called to determine whether a
* connection to a database is valid or invalid. A typical client
* can determine that a connection is invalid by catching any
* exceptions that might be thrown when an operation is attempted.
*
* @return true
if this Connection
object
* is closed; false
if it is still open
* @exception SQLException if a database access error occurs
*/
public synchronized boolean isClosed() throws SQLException {
return isClosed;
}
//======================================================================
// Advanced features:
/**
*
*
* Retrieves a DatabaseMetaData
object that contains
* metadata about the database to which this
* Connection
object represents a connection.
* The metadata includes information about the database's
* tables, its supported SQL grammar, its stored
* procedures, the capabilities of this connection, and so on.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 essentially supports full database metadata.
*
* For discussion in greater detail, please follow the link to the
* overview for JDBCDatabaseMetaData, below.
*
*
*
* @return a DatabaseMetaData
object for this
* Connection
object
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification)
* or this method is called on a closed connection
* @see JDBCDatabaseMetaData
*/
public synchronized DatabaseMetaData getMetaData() throws SQLException {
checkClosed();
return new JDBCDatabaseMetaData(this);
}
/**
*
*
* Puts this connection in read-only mode as a hint to the driver to enable
* database optimizations.
*
* Note: This method cannot be called during a transaction.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 supports the SQL standard, which will not allow calls to
* this method to succeed during a transaction.
*
* Additionally, HSQLDB provides a way to put a whole database in
* read-only mode. This is done by manually adding the line
* 'readonly=true' to the database's .properties file while the
* database is offline. Upon restart, all connections will be
* readonly, since the entire database will be readonly. To take
* a database out of readonly mode, simply take the database
* offline and remove the line 'readonly=true' from the
* database's .properties file. Upon restart, the database will
* be in regular (read-write) mode.
*
* When a database is put in readonly mode, its files are opened
* in readonly mode, making it possible to create CD-based
* readonly databases. To create a CD-based readonly database
* that has CACHED tables and whose .data file is suspected of
* being highly fragmented, it is recommended that the database
* first be SHUTDOWN COMPACTed before copying the database
* files to CD. This will reduce the space required and may
* improve access times against the .data file which holds the
* CACHED table data.
*
* Starting with 1.7.2, an alternate approach to opimizing the
* .data file before creating a CD-based readonly database is to issue
* the CHECKPOINT DEFRAG command followed by SHUTDOWN to take the
* database offline in preparation to burn the database files to CD.
*
*
*
* @param readOnly true
enables read-only mode;
* false
disables it
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection or this
* method is called during a transaction
*/
public synchronized void setReadOnly(
boolean readOnly) throws SQLException {
checkClosed();
try {
sessionProxy.setReadOnlyDefault(readOnly);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
* Retrieves whether this Connection
* object is in read-only mode.
*
* @return true
if this Connection
object
* is read-only; false
otherwise
* @exception SQLException SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
*/
public synchronized boolean isReadOnly() throws SQLException {
checkClosed();
try {
return sessionProxy.isReadOnlyDefault();
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Sets the given catalog name in order to select
* a subspace of this Connection
object's database
* in which to work.
*
*
* (JDBC4 Clarification:)
* If the driver does not support catalogs, it will
* silently ignore this request.
* JDBC 4.1[
* Calling {@code setCatalog} has no effect on previously created or prepared
* {@code Statement} objects. It is implementation defined whether a DBMS
* prepare operation takes place immediately when the {@code Connection}
* method {@code prepareStatement} or {@code prepareCall} is invoked.
* For maximum portability, {@code setCatalog} should be called before a
* {@code Statement} is created or prepared.]
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB supports a single catalog per database. If the given catalog name
* is not the same as the database catalog name, this method throws an
* error.
*
*
* @param catalog the name of a catalog (subspace in this
* Connection
object's database) in which to work
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification)
* or this method is called on a closed connection
* @see #getCatalog
*/
public synchronized void setCatalog(String catalog) throws SQLException {
checkClosed();
try {
sessionProxy.setAttribute(SessionInterface.INFO_CATALOG, catalog);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Retrieves this Connection
object's current catalog name.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB supports a single catalog per database. This method
* returns the catalog name for the current database
* error.
*
*
*
* @return the current catalog name or null
if there is none
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @see #setCatalog
*/
public synchronized String getCatalog() throws SQLException {
checkClosed();
try {
return (String) sessionProxy.getAttribute(
SessionInterface.INFO_CATALOG);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Attempts to change the transaction isolation level for this
* Connection
object to the one given.
* The constants defined in the interface Connection
* are the possible transaction isolation levels.
*
* Note: If this method is called during a transaction, the result
* is implementation-defined.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 accepts all isolation levels. Connection.TRANSACTION_READ_UNCOMMITED
* is promoted to Connection.TRANSACTION_READ_COMMITED, but the transactions become read only
.
* Calling this method during a transaction always succeeds and the selected
* isolation level is used from the next transaction.
*
*
*
* @param level one of the following Connection
constants:
* Connection.TRANSACTION_READ_UNCOMMITTED
,
* Connection.TRANSACTION_READ_COMMITTED
,
* Connection.TRANSACTION_REPEATABLE_READ
, or
* Connection.TRANSACTION_SERIALIZABLE
.
* (Note that Connection.TRANSACTION_NONE
cannot be used
* because it specifies that transactions are not supported.)
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 End Clarification)
* or the given parameter is not one of the Connection
* constants
* @see JDBCDatabaseMetaData#supportsTransactionIsolationLevel
* @see #getTransactionIsolation
*/
public synchronized void setTransactionIsolation(
int level) throws SQLException {
checkClosed();
switch (level) {
case TRANSACTION_READ_UNCOMMITTED :
case TRANSACTION_READ_COMMITTED :
case TRANSACTION_REPEATABLE_READ :
case TRANSACTION_SERIALIZABLE :
break;
default :
throw JDBCUtil.invalidArgument();
}
try {
sessionProxy.setIsolationDefault(level);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Retrieves this Connection
object's current
* transaction isolation level.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 supports all isolation levels. Connection.TRANSACTION_READ_UNCOMMITED
* is promoted to Connection.TRANSACTION_READ_COMMITED
.
*
*
*
* @return the current transaction isolation level, which will be one
* of the following constants:
* Connection.TRANSACTION_READ_UNCOMMITTED
,
* Connection.TRANSACTION_READ_COMMITTED
,
* Connection.TRANSACTION_REPEATABLE_READ
,
* Connection.TRANSACTION_SERIALIZABLE
, or
* Connection.TRANSACTION_NONE
.
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @see JDBCDatabaseMetaData#supportsTransactionIsolationLevel
* @see #setTransactionIsolation
*/
public synchronized int getTransactionIsolation() throws SQLException {
checkClosed();
try {
return sessionProxy.getIsolation();
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Retrieves the first warning reported by calls on this
* Connection
object. If there is more than one
* warning, subsequent warnings will be chained to the first one
* and can be retrieved by calling the method
* SQLWarning.getNextWarning
on the warning
* that was retrieved previously.
*
* This method may not be
* called on a closed connection; doing so will cause an
* SQLException
to be thrown.
*
*
Note: Subsequent warnings will be chained to this
* SQLWarning.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB produces warnings whenever a createStatement(),
* prepareStatement() or prepareCall() invocation requests an unsupported
* but defined combination of result set type, concurrency and holdability,
* such that another set is substituted.
* Other warnings are typically raised during the execution of data change
* and query statements.
*
* Only the warnings caused by the last operation on this connection are
* returned by this method. A single operation may return up to 10 chained
* warnings.
*
*
* @return the first SQLWarning
object or null
* if there are none
* @exception SQLException if a database access error occurs or
* this method is called on a closed connection
* @see java.sql.SQLWarning
*/
public synchronized SQLWarning getWarnings() throws SQLException {
checkClosed();
return rootWarning;
}
/**
*
*
* Clears all warnings reported for this Connection
object.
* After a call to this method, the method getWarnings
* returns null
until a new warning is
* reported for this Connection
object.
*
*
*
*
* HSQLDB-Specific Information:
*
* The standard behaviour is implemented.
*
*
*
* @exception SQLException SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
*/
public synchronized void clearWarnings() throws SQLException {
checkClosed();
rootWarning = null;
}
//--------------------------JDBC 2.0-----------------------------
/**
*
*
* Creates a Statement
object that will generate
* ResultSet
objects with the given type and concurrency.
* This method is the same as the createStatement
method
* above, but it allows the default result set
* type and concurrency to be overridden.
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
* interpretation of of resultSetType and resultSetConcurrency has
* changed in this version.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
,
* CONCUR_READ_ONLY
,
* CONCUR_UPDATABLE
* results.
*
* If an unsupported combination is requested, a SQLWarning is issued on
* this Connection and the closest supported combination is used instead.
*
*
*
* @param resultSetType a result set type; one of
* ResultSet.TYPE_FORWARD_ONLY
,
* ResultSet.TYPE_SCROLL_INSENSITIVE
, or
* ResultSet.TYPE_SCROLL_SENSITIVE
* @param resultSetConcurrency a concurrency type; one of
* ResultSet.CONCUR_READ_ONLY
or
* ResultSet.CONCUR_UPDATABLE
* @return a new Statement
object that will generate
* ResultSet
objects with the given type and
* concurrency
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameters are not ResultSet
* constants indicating type and concurrency
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method or this method is not supported for the specified result
* set type and result set concurrency.
* @since JDK 1.2
*/
public synchronized Statement createStatement(int resultSetType,
int resultSetConcurrency) throws SQLException {
checkClosed();
int props = ResultProperties.getValueForJDBC(resultSetType,
resultSetConcurrency, rsHoldability);
return new JDBCStatement(this, props);
}
/**
*
*
* Creates a PreparedStatement
object that will generate
* ResultSet
objects with the given type and concurrency.
* This method is the same as the prepareStatement
method
* above, but it allows the default result set
* type and concurrency to be overridden.
* (JDBC4 Clarification:)
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
* interpretation of of resultSetType and resultSetConcurrency has
* changed in this version.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
,
* CONCUR_READ_ONLY
,
* CONCUR_UPDATABLE
* results.
*
* If an unsupported combination is requested, a SQLWarning is issued on
* this Connection and the closest supported combination is used instead.
*
*
*
* @param sql a String
object that is the SQL statement to
* be sent to the database; may contain one or more '?' IN
* parameters
* @param resultSetType a result set type; one of
* ResultSet.TYPE_FORWARD_ONLY
,
* ResultSet.TYPE_SCROLL_INSENSITIVE
, or
* ResultSet.TYPE_SCROLL_SENSITIVE
* @param resultSetConcurrency a concurrency type; one of
* ResultSet.CONCUR_READ_ONLY
or
* ResultSet.CONCUR_UPDATABLE
* @return a new PreparedStatement object containing the
* pre-compiled SQL statement that will produce ResultSet
* objects with the given type and concurrency
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameters are not ResultSet
* constants indicating type and concurrency
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method or this method is not supported for the specified result
* set type and result set concurrency.
* @since JDK 1.2
*/
public synchronized PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency) throws SQLException {
checkClosed();
try {
return new JDBCPreparedStatement(this, sql, resultSetType,
resultSetConcurrency, rsHoldability,
ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Creates a CallableStatement
object that will generate
* ResultSet
objects with the given type and concurrency.
* This method is the same as the prepareCall
method
* above, but it allows the default result set
* type and concurrency to be overridden.
* (JDBC4 Clarification:)
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
* interpretation of of resultSetType and resultSetConcurrency has
* changed in this version.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
,
* CONCUR_READ_ONLY
,
* CONCUR_UPDATABLE
* results.
*
* If an unsupported combination is requested, a SQLWarning is issued on
* this Connection and the closest supported combination is used instead.
*
*
*
* @param sql a String
object that is the SQL statement to
* be sent to the database; may contain on or more '?' parameters
* @param resultSetType a result set type; one of
* ResultSet.TYPE_FORWARD_ONLY
,
* ResultSet.TYPE_SCROLL_INSENSITIVE
, or
* ResultSet.TYPE_SCROLL_SENSITIVE
* @param resultSetConcurrency a concurrency type; one of
* ResultSet.CONCUR_READ_ONLY
or
* ResultSet.CONCUR_UPDATABLE
* @return a new CallableStatement
object containing the
* pre-compiled SQL statement that will produce ResultSet
* objects with the given type and concurrency
* @exception SQLException if a database access error occurs, this method
* (JDBC4 Clarification:)
* is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameters are not ResultSet
* constants indicating type and concurrency
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method or this method is not supported for the specified result
* set type and result set concurrency.
* @since JDK 1.2
*/
public synchronized CallableStatement prepareCall(String sql,
int resultSetType, int resultSetConcurrency) throws SQLException {
checkClosed();
try {
return new JDBCCallableStatement(this, sql, resultSetType,
resultSetConcurrency, rsHoldability);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Retrieves the Map
object associated with this
* Connection
object.
* Unless the application has added an entry, the type map returned
* will be empty.
* JDBC 4.1[
* You must invoke setTypeMap
after making changes to the
* Map
object returned from
* getTypeMap
as a JDBC driver may create an internal
* copy of the Map
object passed to setTypeMap
:
*
* Map<String,Class<?>> myMap = con.getTypeMap();
* myMap.put("mySchemaName.ATHLETES", Athletes.class);
* con.setTypeMap(myMap);
*
]
*
*
*
* HSQLDB-Specific Information:
*
* For compatibility, HSQLDB returns an empty map.
*
*
*
* @return the java.util.Map
object associated
* with this Connection
object
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.2
* @see #setTypeMap
*/
public synchronized java.util
.Map> getTypeMap() throws SQLException {
checkClosed();
return new java.util.HashMap>();
}
/**
*
*
* Installs the given TypeMap
object as the type map for
* this Connection
object. The type map will be used for the
* custom mapping of SQL structured types and distinct types.
* JDBC4.1[
* You must set the the values for the TypeMap
prior to
* calling setMap
as a JDBC driver may create an internal copy
* of the TypeMap
:
*
*
* Map myMap<String,Class<?>> = new HashMap<String,Class<?>>();
* myMap.put("mySchemaName.ATHLETES", Athletes.class);
* con.setTypeMap(myMap);
*
]
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB does not yet support this feature. Calling this
* method always throws a SQLException
, stating that
* the function is not supported.
*
*
*
* @param map the java.util.Map
object to install
* as the replacement for this Connection
* object's default type map
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection or
* (:JDBC4 Clarification)
* the given parameter is not a java.util.Map
* object
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.2
* @see #getTypeMap
*/
public synchronized void setTypeMap(Map> map) throws SQLException {
checkClosed();
throw JDBCUtil.notSupported();
}
//--------------------------JDBC 3.0-----------------------------
/**
*
*
* (JDBC4 Clarification:)
* Changes the default holdability of ResultSet
objects
* created using this Connection
object to the given
* holdability. The default holdability of ResultSet
objects
* can be be determined by invoking
* {@link DatabaseMetaData#getResultSetHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB supports this feature.
*
*
* @param holdability a ResultSet
holdability constant; one of
* ResultSet.HOLD_CURSORS_OVER_COMMIT
or
* ResultSet.CLOSE_CURSORS_AT_COMMIT
* @throws SQLException if a database access occurs, this method is called
* (JDBC4 Clarification:)
* on a closed connection, or the given parameter
* (JDBC4 Clarification:)
* is not a ResultSet
constant indicating holdability
* @exception SQLFeatureNotSupportedException if the given holdability is not supported
* @see #getHoldability
* @see DatabaseMetaData#getResultSetHoldability
* @see JDBCResultSet
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized void setHoldability(
int holdability) throws SQLException {
checkClosed();
switch (holdability) {
case JDBCResultSet.HOLD_CURSORS_OVER_COMMIT :
case JDBCResultSet.CLOSE_CURSORS_AT_COMMIT :
break;
default :
throw JDBCUtil.invalidArgument();
}
rsHoldability = holdability;
}
/**
*
*
* Retrieves the current holdability of ResultSet
objects
* created using this Connection
object.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB returns the current holdability.
*
* The default is HOLD_CURSORS_OVER_COMMIT.
*
*
*
* @return the holdability, one of
* ResultSet.HOLD_CURSORS_OVER_COMMIT
or
* ResultSet.CLOSE_CURSORS_AT_COMMIT
* @throws SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @see #setHoldability
* @see DatabaseMetaData#getResultSetHoldability
* @see JDBCResultSet
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized int getHoldability() throws SQLException {
checkClosed();
return rsHoldability;
}
/**
*
*
* Creates an unnamed savepoint in the current transaction and
* returns the new Savepoint
object that represents it.
*
* (JDBC4 clarification:) if setSavepoint is invoked outside of an active transaction, a transaction will be started at this newly created
* savepoint.
*
*
*
*
* HSQLDB-Specific Information:
*
* From 2.0, HSQLDB supports this feature.
*
* Note: Unnamed savepoints are not part of the SQL:2003 standard.
* Use setSavepoint(String name) instead.
*
*
*
* @return the new Savepoint
object
* @exception SQLException if a database access error occurs,
* (JDBC4 Clarification:)
* this method is called while participating in a distributed transaction,
* this method is called on a closed connection
* or this Connection
object is currently in
* auto-commit mode
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see JDBCSavepoint
* @see java.sql.Savepoint
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized Savepoint setSavepoint() throws SQLException {
checkClosed();
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
throw JDBCUtil.sqlException(ErrorCode.X_3B001);
}
JDBCSavepoint savepoint = new JDBCSavepoint(this);
try {
sessionProxy.savepoint(savepoint.name);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
return savepoint;
}
/**
*
*
* Creates a savepoint with the given name in the current transaction
* and returns the new Savepoint
object that represents it.
*
* if setSavepoint is invoked outside of an active transaction, a transaction will be started at this newly created
* savepoint.
*
*
*
*
*
* HSQLDB-Specific Information:
*
* Previous to JDBC 4, if the connection is autoCommit,
* setting a savepoint has no effect, as it is cleared upon the execution
* of the next transactional statement. When built for JDBC 4, this method
* throws an SQLException when this Connection
object is currently
* in auto-commit mode, as per the JDBC 4 standard.
*
*
* @param name a String
containing the name of the savepoint
* @return the new Savepoint
object
* @exception SQLException if a database access error occurs,
* (JDBC4 Clarification:)
* this method is called while participating in a distributed transaction,
* this method is called on a closed connection
* or this Connection
object is currently in
* auto-commit mode
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see JDBCSavepoint
* @see java.sql.Savepoint
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized Savepoint setSavepoint(
String name) throws SQLException {
checkClosed();
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
throw JDBCUtil.sqlException(ErrorCode.X_3B001);
}
if (name == null) {
throw JDBCUtil.nullArgument();
}
if (name.startsWith("SYSTEM_SAVEPOINT_")) {
throw JDBCUtil.invalidArgument();
}
try {
sessionProxy.savepoint(name);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
return new JDBCSavepoint(name, this);
}
/**
*
*
* Undoes all changes made after the given Savepoint
object
* was set.
*
* This method should be used only when auto-commit has been disabled.
*
*
*
*
* HSQLDB-Specific Information:
*
* Previous to JDBC 4, JDBCSavepoint
objects are valid for the life of
* the originating Connection
object and hence can be used
* interchangeably, as long as they have equal savepoint names.
*
* When built for JDBC 4, JDBCConnection
objects invalidate
* JDBCSavepoint
objects when auto-commit mode is entered as well
* as when they are used to successfully release or roll back to a named SQL
* savepoint. As per the JDBC 4 standard, when built for JDBC 4, this
* method throws an SQLException
when this Connection
* object is currently in auto-commit mode and an invalidated
* JDBCSavepoint
is specified.
*
*
* @param savepoint the Savepoint
object to roll back to
* @exception SQLException if a database access error occurs,
* this method is called while participating in a distributed transaction,
* this method is called on a closed connection,
* the Savepoint
object is no longer valid,
* or this Connection
object is currently in
* auto-commit mode
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see JDBCSavepoint
* @see java.sql.Savepoint
* @see #rollback
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized void rollback(
Savepoint savepoint) throws SQLException {
JDBCSavepoint sp;
checkClosed();
if (savepoint == null) {
throw JDBCUtil.nullArgument();
}
if (!(savepoint instanceof JDBCSavepoint)) {
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
sp = (JDBCSavepoint) savepoint;
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && sp.name == null) {
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
if (this != sp.connection) {
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
sp.name = null;
sp.connection = null;
throw JDBCUtil.sqlException(ErrorCode.X_3B001);
}
try {
sessionProxy.rollbackToSavepoint(sp.name);
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4) {
sp.connection = null;
sp.name = null;
}
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Removes the specified Savepoint
(JDBC4 Clarification:) and subsequent Savepoint
objects from the current
* transaction. Any reference to the savepoint after it have been removed
* will cause an SQLException
to be thrown.
*
*
*
*
* HSLQDB Note:
*
* Previous to JDBC 4, JDBCSavepoint
objects are valid for the life of
* the originating Connection
object and hence can be used
* interchangeably, as long as they have equal savepoint names.
*
* When built for JDBC 4, JDBCConnection
objects invalidate
* JDBCSavepoint
objects when auto-commit mode is entered as well
* as when they are used to successfully release or roll back to a named SQL
* savepoint. As per the JDBC 4 standard, when built for JDBC 4, this
* method throws an SQLException
when this Connection
* object is currently in auto-commit mode and when an invalidated
* JDBCSavepoint
is specified.
*
* @param savepoint the Savepoint
object to be removed
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection or
* the given Savepoint
object is not a valid
* savepoint in the current transaction
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see JDBCSavepoint
* @see java.sql.Savepoint
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized void releaseSavepoint(
Savepoint savepoint) throws SQLException {
JDBCSavepoint sp;
Result req;
checkClosed();
if (savepoint == null) {
throw JDBCUtil.nullArgument();
}
if (!(savepoint instanceof JDBCSavepoint)) {
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
sp = (JDBCSavepoint) savepoint;
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && sp.name == null) {
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
if (this != sp.connection) {
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4 && getAutoCommit()) {
sp.name = null;
sp.connection = null;
throw JDBCUtil.invalidArgument(ErrorCode.X_3B001);
}
try {
sessionProxy.releaseSavepoint(sp.name);
if (JDBCDatabaseMetaData.JDBC_MAJOR >= 4) {
sp.connection = null;
sp.name = null;
}
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Creates a Statement
object that will generate
* ResultSet
objects with the given type, concurrency,
* and holdability.
* This method is the same as the createStatement
method
* above, but it allows the default result set
* type, concurrency, and holdability to be overridden.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
* interpretation of of resultSetType and resultSetConcurrency has
* changed in this version.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
,
* CONCUR_READ_ONLY
,
* CONCUR_UPDATABLE
* results.
*
* If an unsupported combination is requested, a SQLWarning is issued on
* this Connection and the closest supported combination is used instead.
*
*
*
* @param resultSetType one of the following ResultSet
* constants:
* ResultSet.TYPE_FORWARD_ONLY
,
* ResultSet.TYPE_SCROLL_INSENSITIVE
, or
* ResultSet.TYPE_SCROLL_SENSITIVE
* @param resultSetConcurrency one of the following ResultSet
* constants:
* ResultSet.CONCUR_READ_ONLY
or
* ResultSet.CONCUR_UPDATABLE
* @param resultSetHoldability one of the following ResultSet
* constants:
* ResultSet.HOLD_CURSORS_OVER_COMMIT
or
* ResultSet.CLOSE_CURSORS_AT_COMMIT
* @return a new Statement
object that will generate
* ResultSet
objects with the given type,
* concurrency, and holdability
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameters are not ResultSet
* constants indicating type, concurrency, and holdability
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method or this method is not supported for the specified result
* set type, result set holdability and result set concurrency.
* @see JDBCResultSet
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized Statement createStatement(int resultSetType,
int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
checkClosed();
int props = ResultProperties.getValueForJDBC(resultSetType,
resultSetConcurrency, resultSetHoldability);
return new JDBCStatement(this, props);
}
/**
*
*
* Creates a PreparedStatement
object that will generate
* ResultSet
objects with the given type, concurrency,
* and holdability.
*
* This method is the same as the prepareStatement
method
* above, but it allows the default result set
* type, concurrency, and holdability to be overridden.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
* interpretation of of resultSetType and resultSetConcurrency has
* changed in this version.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
,
* CONCUR_READ_ONLY
,
* CONCUR_UPDATABLE
* results.
* HOLD_CURSORS_OVER_COMMIT
is supported only when
* CONCUR_READ_ONLY
is requested.
*
*
* If an unsupported combination is requested, a SQLWarning is issued on
* this Connection and the closest supported combination is used instead.
*
*
*
* @param sql a String
object that is the SQL statement to
* be sent to the database; may contain one or more '?' IN
* parameters
* @param resultSetType one of the following ResultSet
* constants:
* ResultSet.TYPE_FORWARD_ONLY
,
* ResultSet.TYPE_SCROLL_INSENSITIVE
, or
* ResultSet.TYPE_SCROLL_SENSITIVE
* @param resultSetConcurrency one of the following ResultSet
* constants:
* ResultSet.CONCUR_READ_ONLY
or
* ResultSet.CONCUR_UPDATABLE
* @param resultSetHoldability one of the following ResultSet
* constants:
* ResultSet.HOLD_CURSORS_OVER_COMMIT
or
* ResultSet.CLOSE_CURSORS_AT_COMMIT
* @return a new PreparedStatement
object, containing the
* pre-compiled SQL statement, that will generate
* ResultSet
objects with the given type,
* concurrency, and holdability
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameters are not ResultSet
* constants indicating type, concurrency, and holdability
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method or this method is not supported for the specified result
* set type, result set holdability and result set concurrency.
* @see JDBCResultSet
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized PreparedStatement prepareStatement(String sql,
int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
checkClosed();
try {
return new JDBCPreparedStatement(this, sql, resultSetType,
resultSetConcurrency, resultSetHoldability,
ResultConstants.RETURN_NO_GENERATED_KEYS, null, null);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Creates a CallableStatement
object that will generate
* ResultSet
objects with the given type and concurrency.
* This method is the same as the prepareCall
method
* above, but it allows the default result set
* type, result set concurrency type and holdability to be overridden.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0 adheres closely to SQL and JDBC standards. The
* interpretation of of resultSetType and resultSetConcurrency has
* changed in this version.
*
* HSQLDB supports TYPE_FORWARD_ONLY
,
* TYPE_SCROLL_INSENSITIVE
,
* CONCUR_READ_ONLY
,
* CONCUR_UPDATABLE
* results.
*
* If an unsupported combination is requested, a SQLWarning is issued on
* this Connection and the closest supported combination is used instead.
*
*
*
* @param sql a String
object that is the SQL statement to
* be sent to the database; may contain on or more '?' parameters
* @param resultSetType one of the following ResultSet
* constants:
* ResultSet.TYPE_FORWARD_ONLY
,
* ResultSet.TYPE_SCROLL_INSENSITIVE
, or
* ResultSet.TYPE_SCROLL_SENSITIVE
* @param resultSetConcurrency one of the following ResultSet
* constants:
* ResultSet.CONCUR_READ_ONLY
or
* ResultSet.CONCUR_UPDATABLE
* @param resultSetHoldability one of the following ResultSet
* constants:
* ResultSet.HOLD_CURSORS_OVER_COMMIT
or
* ResultSet.CLOSE_CURSORS_AT_COMMIT
* @return a new CallableStatement
object, containing the
* pre-compiled SQL statement, that will generate
* ResultSet
objects with the given type,
* concurrency, and holdability
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameters are not ResultSet
* constants indicating type, concurrency, and holdability
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method or this method is not supported for the specified result
* set type, result set holdability and result set concurrency.
* @see JDBCResultSet
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized CallableStatement prepareCall(String sql,
int resultSetType, int resultSetConcurrency,
int resultSetHoldability) throws SQLException {
checkClosed();
try {
return new JDBCCallableStatement(this, sql, resultSetType,
resultSetConcurrency, resultSetHoldability);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Creates a default PreparedStatement
object that has
* the capability to retrieve auto-generated keys. The given constant
* tells the driver whether it should make auto-generated keys
* available for retrieval. This parameter is ignored if the SQL statement
* is not an INSERT
statement, or an SQL statement able to return
* auto-generated keys (the list of such statements is vendor-specific).
*
* Note: This method is optimized for handling
* parametric SQL statements that benefit from pre-compilation. If
* the driver supports pre-compilation,
* the method prepareStatement
will send
* the statement to the database for pre-compilation. Some drivers
* may not support pre-compilation. In this case, the statement may
* not be sent to the database until the PreparedStatement
* object is executed. This has no direct effect on users; however, it does
* affect which methods throw certain SQLExceptions.
*
* Result sets created using the returned PreparedStatement
* object will by default be type TYPE_FORWARD_ONLY
* and have a concurrency level of CONCUR_READ_ONLY
.
* (JDBC4 Clarification:)
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with version 2.0, HSQLDB supports returning generated columns
* with single-row and multi-row INSERT, UPDATE and MERGE statements.
* If the table has an IDENTITY or GENERATED column(s) the values for these
* columns are returned in the next call to getGeneratedKeys() after each
* execution of the PreparedStatement.
*
* HSQLDB also supports returning primary key values from he rows by using the
* org.hsqldb.jdbc.JDBCStatement.RETURN_PRIMARY_KEYS
constant.
*
*
*
* @param sql an SQL statement that may contain one or more '?' IN
* parameter placeholders
* @param autoGeneratedKeys a flag indicating whether auto-generated keys
* should be returned; one of
* Statement.RETURN_GENERATED_KEYS
or
* Statement.NO_GENERATED_KEYS
* @return a new PreparedStatement
object, containing the
* pre-compiled SQL statement, that will have the capability of
* returning auto-generated keys
* @exception SQLException if a database access error occurs, this
* (JDBC4 Clarification:)
* method is called on a closed connection
* (:JDBC4 Clarification)
* or the given parameter is not a Statement
* constant indicating whether auto-generated keys should be
* returned
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method with a constant of Statement.RETURN_GENERATED_KEYS
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized PreparedStatement prepareStatement(String sql,
int autoGeneratedKeys) throws SQLException {
checkClosed();
try {
if (autoGeneratedKeys != Statement.RETURN_GENERATED_KEYS
&& autoGeneratedKeys != Statement.NO_GENERATED_KEYS
&& autoGeneratedKeys != JDBCStatement.RETURN_PRIMARY_KEYS) {
throw JDBCUtil.invalidArgument("autoGeneratedKeys");
}
return new JDBCPreparedStatement(this, sql,
JDBCResultSet.TYPE_FORWARD_ONLY,
JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
autoGeneratedKeys, null, null);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
* Creates a default PreparedStatement
object capable
* of returning the auto-generated keys designated by the given array.
* This array contains the indexes of the columns in the target
* table that contain the auto-generated keys that should be made
* available. The driver will ignore the array if the SQL statement
* is not an INSERT
statement, or an SQL statement able to return
* auto-generated keys (the list of such statements is vendor-specific).
*
* An SQL statement with or without IN parameters can be
* pre-compiled and stored in a PreparedStatement
object. This
* object can then be used to efficiently execute this statement
* multiple times.
*
* Note: This method is optimized for handling
* parametric SQL statements that benefit from pre-compilation. If
* the driver supports pre-compilation,
* the method prepareStatement
will send
* the statement to the database for pre-compilation. Some drivers
* may not support pre-compilation. In this case, the statement may
* not be sent to the database until the PreparedStatement
* object is executed. This has no direct effect on users; however, it does
* affect which methods throw certain SQLExceptions.
*
* Result sets created using the returned PreparedStatement
* object will by default be type TYPE_FORWARD_ONLY
* and have a concurrency level of CONCUR_READ_ONLY
.
* (JDBC4 Clarification:)
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with version 2.0, HSQLDB supports returning generated columns
* with single-row and multi-row INSERT, UPDATE and MERGE statements.
* The columnIndexes may specify any set of columns of the table.
*
*
*
* @param sql an SQL statement that may contain one or more '?' IN
* parameter placeholders
* @param columnIndexes an array of column indexes indicating the columns
* that should be returned from the inserted row or rows
* @return a new PreparedStatement
object, containing the
* pre-compiled statement, that is capable of returning the
* auto-generated keys designated by the given array of column
* indexes
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized PreparedStatement prepareStatement(String sql,
int[] columnIndexes) throws SQLException {
checkClosed();
try {
return new JDBCPreparedStatement(this, sql,
JDBCResultSet.TYPE_FORWARD_ONLY,
JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
ResultConstants.RETURN_GENERATED_KEYS_COL_INDEXES,
columnIndexes, null);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
*
*
* Creates a default PreparedStatement
object capable
* of returning the auto-generated keys designated by the given array.
* This array contains the names of the columns in the target
* table that contain the auto-generated keys that should be returned.
* The driver will ignore the array if the SQL statement
* is not an INSERT
statement, or an SQL statement able to return
* auto-generated keys (the list of such statements is vendor-specific).
*
* An SQL statement with or without IN parameters can be
* pre-compiled and stored in a PreparedStatement
object. This
* object can then be used to efficiently execute this statement
* multiple times.
*
* Note: This method is optimized for handling
* parametric SQL statements that benefit from pre-compilation. If
* the driver supports pre-compilation,
* the method prepareStatement
will send
* the statement to the database for pre-compilation. Some drivers
* may not support pre-compilation. In this case, the statement may
* not be sent to the database until the PreparedStatement
* object is executed. This has no direct effect on users; however, it does
* affect which methods throw certain SQLExceptions.
*
* Result sets created using the returned PreparedStatement
* object will by default be type TYPE_FORWARD_ONLY
* and have a concurrency level of CONCUR_READ_ONLY
.
* (JDBC4 Clarification:)
* The holdability of the created result sets can be determined by
* calling {@link #getHoldability}.
*
*
*
*
* HSQLDB-Specific Information:
*
* Starting with version 2.0, HSQLDB supports returning generated columns
* with single-row and multi-row INSERT, UPDATE and MERGE statements.
* The columnNames may specify any set of columns of the table. The names
* are case-sensitive, unlike column names in ResultSet methods.
*
*
*
* @param sql an SQL statement that may contain one or more '?' IN
* parameter placeholders
* @param columnNames an array of column names indicating the columns
* that should be returned from the inserted row or rows
* @return a new PreparedStatement
object, containing the
* pre-compiled statement, that is capable of returning the
* auto-generated keys designated by the given array of column
* names
* @exception SQLException if a database access error occurs
* (JDBC4 Clarification:)
* or this method is called on a closed connection
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since JDK 1.4, HSQLDB 1.7.2
*/
public synchronized PreparedStatement prepareStatement(String sql,
String[] columnNames) throws SQLException {
checkClosed();
try {
return new JDBCPreparedStatement(this, sql,
JDBCResultSet.TYPE_FORWARD_ONLY,
JDBCResultSet.CONCUR_READ_ONLY, rsHoldability,
ResultConstants.RETURN_GENERATED_KEYS_COL_NAMES, null,
columnNames);
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
//------------------------- JDBC 4.0 -----------------------------------
/**
* Constructs an object that implements the Clob
interface. The object
* returned initially contains no data. The setAsciiStream
,
* setCharacterStream
and setString
methods of
* the Clob
interface may be used to add data to the Clob
.
* @return An object that implements the Clob
interface
* @throws SQLException if an object that implements the
* Clob
interface can not be constructed, this method is
* called on a closed connection or a database access error occurs.
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this data type
*
* @since JDK 1.6, HSQLDB 2.0
*/
public Clob createClob() throws SQLException {
checkClosed();
return new JDBCClob();
}
/**
* Constructs an object that implements the Blob
interface. The object
* returned initially contains no data. The setBinaryStream
and
* setBytes
methods of the Blob
interface may be used to add data to
* the Blob
.
* @return An object that implements the Blob
interface
* @throws SQLException if an object that implements the
* Blob
interface can not be constructed, this method is
* called on a closed connection or a database access error occurs.
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this data type
*
* @since JDK 1.6, HSQLDB 2.0
*/
public Blob createBlob() throws SQLException {
checkClosed();
return new JDBCBlob();
}
/**
* Constructs an object that implements the NClob
interface. The object
* returned initially contains no data. The setAsciiStream
,
* setCharacterStream
and setString
methods of the NClob
interface may
* be used to add data to the NClob
.
* @return An object that implements the NClob
interface
* @throws SQLException if an object that implements the
* NClob
interface can not be constructed, this method is
* called on a closed connection or a database access error occurs.
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this data type
*
* @since JDK 1.6, HSQLDB 2.0
*/
public NClob createNClob() throws SQLException {
checkClosed();
return new JDBCNClob();
}
/**
* Constructs an object that implements the SQLXML
interface. The object
* returned initially contains no data. The createXmlStreamWriter
object and
* setString
method of the SQLXML
interface may be used to add data to the SQLXML
* object.
* @return An object that implements the SQLXML
interface
* @throws SQLException if an object that implements the SQLXML
interface can not
* be constructed, this method is
* called on a closed connection or a database access error occurs.
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this data type
* @since JDK 1.6, HSQLDB 2.0
*/
public SQLXML createSQLXML() throws SQLException {
checkClosed();
return new JDBCSQLXML();
}
/* @todo: ThreadPool? HsqlTimer with callback? */
/**
*
*
* Returns true if the connection has not been closed and is still valid.
* The driver shall submit a query on the connection or use some other
* mechanism that positively verifies the connection is still valid when
* this method is called.
*
* The query submitted by the driver to validate the connection shall be
* executed in the context of the current transaction.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB uses a maximum timeout of 60 seconds if timeout has been specified
* as zero.
*
*
*
* @param timeout - The time in seconds to wait for the database operation
* used to validate the connection to complete. If
* the timeout period expires before the operation
* completes, this method returns false. A value of
* 0 indicates a timeout is not applied to the
* database operation.
*
* @return true if the connection is valid, false otherwise
* @exception SQLException if the value supplied for timeout
* is less then 0
* @since JDK 1.6, HSQLDB 2.0
*
* @see JDBCDatabaseMetaData#getClientInfoProperties
*/
public boolean isValid(int timeout) throws SQLException {
if (timeout < 0) {
throw JDBCUtil.outOfRangeArgument("timeout: " + timeout);
}
if (this.isInternal) {
return true;
} else if (!this.isNetConn) {
return !this.isClosed();
} else if (this.isClosed()) {
return false;
}
final boolean[] flag = new boolean[] { true };
Thread t = new Thread() {
public void run() {
try {
getMetaData().getDatabaseMajorVersion();
} catch (Throwable e) {
flag[0] = false;
}
}
};
if (timeout > 60) {
timeout = 60;
}
// Remember: param is in *seconds*
timeout *= 1000;
try {
t.start();
final long start = System.currentTimeMillis();
t.join(timeout);
try {
t.setContextClassLoader(null);
} catch (Throwable th) {
}
if (timeout == 0) {
return flag[0];
}
return flag[0] && (System.currentTimeMillis() - start) < timeout;
} catch (Throwable e) {
return false;
}
}
/* @todo 20051207 */
/**
* Sets the value of the client info property specified by name to the
* value specified by value.
*
* Applications may use the DatabaseMetaData.getClientInfoProperties
* method to determine the client info properties supported by the driver
* and the maximum length that may be specified for each property.
*
* The driver stores the value specified in a suitable location in the
* database. For example in a special register, session parameter, or
* system table column. For efficiency the driver may defer setting the
* value in the database until the next time a statement is executed or
* prepared. Other than storing the client information in the appropriate
* place in the database, these methods shall not alter the behavior of
* the connection in anyway. The values supplied to these methods are
* used for accounting, diagnostics and debugging purposes only.
*
* The driver shall generate a warning if the client info name specified
* is not recognized by the driver.
*
* If the value specified to this method is greater than the maximum
* length for the property the driver may either truncate the value and
* generate a warning or generate a SQLClientInfoException
. If the driver
* generates a SQLClientInfoException
, the value specified was not set on the
* connection.
*
* The following are standard client info properties. Drivers are not
* required to support these properties however if the driver supports a
* client info property that can be described by one of the standard
* properties, the standard property name should be used.
*
*
* - ApplicationName - The name of the application currently utilizing
* the connection
* - ClientUser - The name of the user that the application using
* the connection is performing work for. This may
* not be the same as the user name that was used
* in establishing the connection.
* - ClientHostname - The host name of the computer the application
* using the connection is running on.
*
*
*
*
* HSQLDB-Specific Information:
*
* HSQLDB 2.0, throws an SQLClientInfoException when this method is
* called.
*
*
*
* @param name The name of the client info property to set
* @param value The value to set the client info property to. If the
* value is null, the current value of the specified
* property is cleared.
*
* @throws SQLClientInfoException if the database server returns an error while
* setting the client info value on the database server or this method
* is called on a closed connection
*
* @since JDK 1.6, HSQLDB 2.0
*/
public void setClientInfo(String name,
String value) throws SQLClientInfoException {
SQLClientInfoException ex = new SQLClientInfoException();
ex.initCause(JDBCUtil.notSupported());
throw ex;
}
/* @todo 20051207 */
/**
* Sets the value of the connection's client info properties. The
* Properties
object contains the names and values of the client info
* properties to be set. The set of client info properties contained in
* the properties list replaces the current set of client info properties
* on the connection. If a property that is currently set on the
* connection is not present in the properties list, that property is
* cleared. Specifying an empty properties list will clear all of the
* properties on the connection. See setClientInfo (String, String)
for
* more information.
*
* If an error occurs in setting any of the client info properties, a
* SQLClientInfoException
is thrown. The SQLClientInfoException
* contains information indicating which client info properties were not set.
* The state of the client information is unknown because
* some databases do not allow multiple client info properties to be set
* atomically. For those databases, one or more properties may have been
* set before the error occurred.
*
*
* @param properties the list of client info properties to set
*
* @see java.sql.Connection#setClientInfo(String, String) setClientInfo(String, String)
* @since JDK 1.6, HSQLDB 2.0
*
* @throws SQLClientInfoException if the database server returns an error while
* setting the clientInfo values on the database server or this method
* is called on a closed connection
*
*/
public void setClientInfo(
Properties properties) throws SQLClientInfoException {
if (!this.isClosed && (properties == null || properties.isEmpty())) {
return;
}
SQLClientInfoException ex = new SQLClientInfoException();
if (this.isClosed) {
ex.initCause(JDBCUtil.connectionClosedException());
} else {
ex.initCause(JDBCUtil.notSupported());
}
throw ex;
}
/* @todo 1.9.0 */
/**
* Returns the value of the client info property specified by name. This
* method may return null if the specified client info property has not
* been set and does not have a default value. This method will also
* return null if the specified client info property name is not supported
* by the driver.
*
* Applications may use the DatabaseMetaData.getClientInfoProperties
* method to determine the client info properties supported by the driver.
*
* @param name The name of the client info property to retrieve
*
* @return The value of the client info property specified
*
* @throws SQLException if the database server returns an error when
* fetching the client info value from the database
* or this method is called on a closed connection
*
* @since JDK 1.6, HSQLDB 2.0
*
* @see java.sql.DatabaseMetaData#getClientInfoProperties
*/
public String getClientInfo(String name) throws SQLException {
checkClosed();
return null;
}
/* @todo - 1.9 */
/**
* Returns a list containing the name and current value of each client info
* property supported by the driver. The value of a client info property
* may be null if the property has not been set and does not have a
* default value.
*
* @return A Properties
object that contains the name and current value of
* each of the client info properties supported by the driver.
*
* @throws SQLException if the database server returns an error when
* fetching the client info values from the database
* or this method is called on a closed connection
*
* @since JDK 1.6, HSQLDB 2.0
*/
public Properties getClientInfo() throws SQLException {
checkClosed();
return null;
}
// --------------------------- Added: Mustang Build 80 -------------------------
/**
* Factory method for creating Array objects.
*
* Note: When createArrayOf
is used to create an array object
* that maps to a primitive data type, then it is implementation-defined
* whether the Array
object is an array of that primitive
* data type or an array of Object
.
*
* Note: The JDBC driver is responsible for mapping the elements
* Object
array to the default JDBC SQL type defined in
* java.sql.Types for the given class of Object
. The default
* mapping is specified in Appendix B of the JDBC specification. If the
* resulting JDBC type is not the appropriate type for the given typeName then
* it is implementation defined whether an SQLException
is
* thrown or the driver supports the resulting conversion.
*
* @param typeName the SQL name of the type the elements of the array map to. The typeName is a
* database-specific name which may be the name of a built-in type, a user-defined type or a standard SQL type supported by this database. This
* is the value returned by Array.getBaseTypeName
* @param elements the elements that populate the returned object
* @return an Array object whose elements map to the specified SQL type
* @throws SQLException if a database error occurs, the JDBC type is not
* appropriate for the typeName and the conversion is not supported, the typeName is null or this method is called on a closed connection
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this data type
* @since 1.6
*/
public Array createArrayOf(String typeName,
Object[] elements) throws SQLException {
checkClosed();
if (typeName == null) {
throw JDBCUtil.nullArgument();
}
typeName = typeName.toUpperCase();
int typeNumber = Type.getTypeNr(typeName);
if (typeNumber == Integer.MIN_VALUE) {
throw JDBCUtil.invalidArgument(typeName);
}
Type type = Type.getDefaultType(typeNumber);
if (type.isArrayType() || type.isLobType() || type.isRowType()) {
throw JDBCUtil.invalidArgument(typeName);
}
Object[] newData = new Object[elements.length];
try {
for (int i = 0; i < elements.length; i++) {
Object o = type.convertJavaToSQL(sessionProxy, elements[i]);
newData[i] = type.convertToTypeLimits(sessionProxy, o);
}
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
Type arrayType = new ArrayType(type, newData.length);
return new JDBCArray(newData, type, arrayType, this);
}
/**
* Factory method for creating Struct objects.
* @param typeName the SQL type name of the SQL structured type that this Struct
* object maps to. The typeName is the name of a user-defined type that
* has been defined for this database. It is the value returned by
* Struct.getSQLTypeName
.
* @param attributes the attributes that populate the returned object
* @return a Struct object that maps to the given SQL type and is populated with the given attributes
* @throws SQLException if a database error occurs, the typeName is null or this method is called on a closed connection
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support this data type
* @since JDK 1.6_b80, HSQLDB 2.0
*/
public Struct createStruct(String typeName,
Object[] attributes) throws SQLException {
checkClosed();
throw JDBCUtil.notSupported();
}
// ------------------- java.sql.Wrapper implementation ---------------------
/**
* Returns an object that implements the given interface to allow access to
* non-standard methods, or standard methods not exposed by the proxy.
*
* If the receiver implements the interface then the result is the receiver
* or a proxy for the receiver. If the receiver is a wrapper
* and the wrapped object implements the interface then the result is the
* wrapped object or a proxy for the wrapped object. Otherwise return the
* the result of calling unwrap
recursively on the wrapped object
* or a proxy for that result. If the receiver is not a
* wrapper and does not implement the interface, then an SQLException
is thrown.
*
* @param by which the return type is inferred from input parameter.
* @param iface A Class defining an interface that the result must implement.
* @return an object that implements the interface. May be a proxy for the actual implementing object.
* @throws java.sql.SQLException If no object found that implements the interface
* @since JDK 1.6, HSQLDB 2.0
*/
@SuppressWarnings("unchecked")
public T unwrap(java.lang.Class iface) throws java.sql.SQLException {
checkClosed();
if (isWrapperFor(iface)) {
return (T) this;
}
throw JDBCUtil.invalidArgument("iface: " + iface);
}
/**
* Returns true if this either implements the interface argument or is directly or indirectly a wrapper
* for an object that does. Returns false otherwise. If this implements the interface then return true,
* else if this is a wrapper then return the result of recursively calling isWrapperFor
on the wrapped
* object. If this does not implement the interface and is not a wrapper, return false.
* This method should be implemented as a low-cost operation compared to unwrap
so that
* callers can use this method to avoid expensive unwrap
calls that may fail. If this method
* returns true then calling unwrap
with the same argument should succeed.
*
* @param iface a Class defining an interface.
* @return true if this implements the interface or directly or indirectly wraps an object that does.
* @throws java.sql.SQLException if an error occurs while determining whether this is a wrapper
* for an object with the given interface.
* @since JDK 1.6, HSQLDB 2.0
*/
public boolean isWrapperFor(
java.lang.Class> iface) throws java.sql.SQLException {
checkClosed();
return (iface != null && iface.isAssignableFrom(this.getClass()));
}
//--------------------------JDBC 4.1 -----------------------------
/**
* Sets the given schema name to access.
*
* If the driver does not support schemas, it will
* silently ignore this request.
*
* Calling {@code setSchema} has no effect on previously created or prepared
* {@code Statement} objects. It is implementation defined whether a DBMS
* prepare operation takes place immediately when the {@code Connection}
* method {@code prepareStatement} or {@code prepareCall} is invoked.
* For maximum portability, {@code setSchema} should be called before a
* {@code Statement} is created or prepared.
*
* @param schema the name of a schema in which to work
* @exception SQLException if a database access error occurs
* or this method is called on a closed connection
* @see #getSchema
* @since JDK 1.7, HSQLDB 2.0.1
*/
public synchronized void setSchema(String schema) throws SQLException {
checkClosed();
if (schema == null) {
throw JDBCUtil.nullArgument("schema");
} else if (schema.length() == 0) {
throw JDBCUtil.invalidArgument("Zero-length schema");
} else {
(new JDBCDatabaseMetaData(this)).setConnectionDefaultSchema(
schema);
}
}
/**
* Retrieves this Connection
object's current schema name.
*
* @return the current schema name or null
if there is none
* @exception SQLException if a database access error occurs
* or this method is called on a closed connection
* @see #setSchema
* @since JDK 1.7 M11 2010/09/10 (b123), HSQLDB 2.0.1
*/
public String getSchema() throws SQLException {
checkClosed();
return new JDBCDatabaseMetaData(this).getConnectionDefaultSchema();
}
/**
* Terminates an open connection. Calling abort
results in:
*
* - The connection marked as closed
*
- Closes any physical connection to the database
*
- Releases resources used by the connection
*
- Insures that any thread that is currently accessing the connection
* will either progress to completion or throw an
SQLException
.
*
*
* Calling abort
marks the connection closed and releases any
* resources. Calling abort
on a closed connection is a
* no-op.
*
* It is possible that the aborting and releasing of the resources that are
* held by the connection can take an extended period of time. When the
* abort
method returns, the connection will have been marked as
* closed and the Executor
that was passed as a parameter to abort
* may still be executing tasks to release resources.
*
* This method checks to see that there is an SQLPermission
* object before allowing the method to proceed. If a
* SecurityManager
exists and its
* checkPermission
method denies calling abort
,
* this method throws a
* java.lang.SecurityException
.
* @param executor The Executor
implementation which will
* be used by abort
.
* @throws java.sql.SQLException if a database access error occurs or
* the {@code executor} is {@code null},
* @throws java.lang.SecurityException if a security manager exists and its
* checkPermission
method denies calling abort
* @see SecurityManager#checkPermission
* @see java.util.concurrent.Executor
* @since JDK 1.7, HSQLDB 2.0.1
*/
public void abort(
java.util.concurrent.Executor executor) throws SQLException {
if (executor == null) {
throw JDBCUtil.nullArgument("executor");
}
close();
}
/**
*
* Sets the maximum period a Connection
or
* objects created from the Connection
* will wait for the database to reply to any one request. If any
* request remains unanswered, the waiting method will
* return with a SQLException
, and the Connection
* or objects created from the Connection
will be marked as
* closed. Any subsequent use of
* the objects, with the exception of the close
,
* isClosed
or Connection.isValid
* methods, will result in a SQLException
.
*
* Note: This method is intended to address a rare but serious
* condition where network partitions can cause threads issuing JDBC calls
* to hang uninterruptedly in socket reads, until the OS TCP-TIMEOUT
* (typically 10 minutes). This method is related to the
* {@link #abort abort() } method which provides an administrator
* thread a means to free any such threads in cases where the
* JDBC connection is accessible to the administrator thread.
* The setNetworkTimeout
method will cover cases where
* there is no administrator thread, or it has no access to the
* connection. This method is severe in it's effects, and should be
* given a high enough value so it is never triggered before any more
* normal timeouts, such as transaction timeouts.
*
* JDBC driver implementations may also choose to support the
* {@code setNetworkTimeout} method to impose a limit on database
* response time, in environments where no network is present.
*
* Drivers may internally implement some or all of their API calls with
* multiple internal driver-database transmissions, and it is left to the
* driver implementation to determine whether the limit will be
* applied always to the response to the API call, or to any
* single request made during the API call.
*
*
* This method can be invoked more than once, such as to set a limit for an
* area of JDBC code, and to reset to the default on exit from this area.
* Invocation of this method has no impact on already outstanding
* requests.
*
* The {@code Statement.setQueryTimeout()} timeout value is independent of the
* timeout value specified in {@code setNetworkTimeout}. If the query timeout
* expires before the network timeout then the
* statement execution will be canceled. If the network is still
* active the result will be that both the statement and connection
* are still usable. However if the network timeout expires before
* the query timeout or if the statement timeout fails due to network
* problems, the connection will be marked as closed, any resources held by
* the connection will be released and both the connection and
* statement will be unusable.
*
* When the driver determines that the {@code setNetworkTimeout} timeout
* value has expired, the JDBC driver marks the connection
* closed and releases any resources held by the connection.
*
*
* This method checks to see that there is an SQLPermission
* object before allowing the method to proceed. If a
* SecurityManager
exists and its
* checkPermission
method denies calling
* setNetworkTimeout
, this method throws a
* java.lang.SecurityException
.
*
* @param executor The Executor
implementation which will
* be used by setNetworkTimeout
.
* @param milliseconds The time in milliseconds to wait for the database
* operation
* to complete. If the JDBC driver does not support milliseconds, the
* JDBC driver will round the value up to the nearest second. If the
* timeout period expires before the operation
* completes, a SQLException will be thrown.
* A value of 0 indicates that there is not timeout for database operations.
* @throws java.sql.SQLException if a database access error occurs, this
* method is called on a closed connection,
* the {@code executor} is {@code null},
* or the value specified for seconds
is less than 0.
* @throws java.lang.SecurityException if a security manager exists and its
* checkPermission
method denies calling
* setNetworkTimeout
.
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see SecurityManager#checkPermission
* @see Statement#setQueryTimeout
* @see #getNetworkTimeout
* @see #abort
* @see java.util.concurrent.Executor
* @since JDK 1.7 M11 2010/09/10 (b123), HSQLDB 2.0.1
*/
public void setNetworkTimeout(java.util.concurrent.Executor executor,
int milliseconds) throws SQLException {
checkClosed();
throw JDBCUtil.notSupported();
}
/**
* Retrieves the number of milliseconds the driver will
* wait for a database request to complete.
* If the limit is exceeded, a
* SQLException
is thrown.
*
* @return the current timeout limit in milliseconds; zero means there is
* no limit
* @throws SQLException if a database access error occurs or
* this method is called on a closed Connection
* @exception SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @see #setNetworkTimeout
* @since JDK 1.7 M11 2010/09/10 (b123), HSQLDB 2.0.1
*/
public int getNetworkTimeout() throws SQLException {
return 0;
}
//---------------------- internal implementation ---------------------------
// -------------------------- Common Attributes ------------------------------
/** Initial holdability */
int rsHoldability = JDBCResultSet.HOLD_CURSORS_OVER_COMMIT;
/** Properties for the connection */
HsqlProperties connProperties;
/** Properties for the session */
HsqlProperties clientProperties;
/**
* This connection's interface to the corresponding Session
* object in the database engine.
*/
SessionInterface sessionProxy;
/**
* Is this an internal connection?
*/
boolean isInternal;
/** Is this connection to a network server instance. */
protected boolean isNetConn;
/**
* Is this connection closed?
*/
boolean isClosed;
/** The first warning in the chain. Null if there are no warnings. */
private SQLWarning rootWarning;
/** Synchronizes concurrent modification of the warning chain */
private final Object rootWarning_mutex = new Object();
/** ID sequence for unnamed savepoints */
private int savepointIDSequence;
/** reuse count in ConnectionPool */
int incarnation;
/** used by a JDBCPool or other custom ConnectionPool instance */
boolean isPooled;
/** used by a JDBCPool or other custom ConnectionPool instance */
JDBCConnectionEventListener poolEventListener;
/** connection URL property close_result indicates to close old result when Statement is reused */
boolean isCloseResultSet;
/** connection URL property use_column_name indicates to return column name in ResultMetadata */
boolean isUseColumnName = true;
/** database property for translation of INTERVAL types to VARCHAR */
boolean isTranslateTTIType = true;
/** connection URL property allow_empty_batch indicates to accept executeBatch() when the batch is empty */
boolean isEmptyBatchAllowed = false;
/** database URL property hsqldb.live_object indicates to store non-serialized object in OTHER columns */
boolean isStoreLiveObject = false;
/**
* Constructs a new external Connection
to an HSQLDB
* Database
.
*
* This constructor is called on behalf of the
* java.sql.DriverManager
when getting a
* Connection
for use in normal (external)
* client code.
*
* Internal client code, that being code located in HSQLDB SQL
* functions and stored procedures, receives an INTERNAL
* connection constructed by the {@link
* #JDBCConnection(org.hsqldb.SessionInterface)
* JDBCConnection(SessionInterface)} constructor.
*
* @param props A Properties
object containing the connection
* properties
* @exception SQLException when the user/password combination is
* invalid, the connection url is invalid, or the
* Database
is unavailable.
*
* The Database
may be unavailable for a number
* of reasons, including network problems or the fact that it
* may already be in use by another process.
*/
public JDBCConnection(HsqlProperties props) throws SQLException {
String user = props.getProperty("user");
String password = props.getProperty("password");
String connType = props.getProperty("connection_type");
String host = props.getProperty("host");
int port = props.getIntegerProperty("port", 0);
String path = props.getProperty("path");
String database = props.getProperty("database");
boolean isTLS = (DatabaseURL.S_HSQLS.equals(connType)
|| DatabaseURL.S_HTTPS.equals(connType));
boolean isTLSWrapper = props.isPropertyTrue(HsqlDatabaseProperties.url_tls_wrapper, false);
isTLSWrapper &= isTLS;
if (user == null) {
user = "SA";
}
if (password == null) {
password = "";
}
Calendar cal = Calendar.getInstance();
int zoneSeconds = HsqlDateTime.getZoneSeconds(cal);
try {
if (DatabaseURL.isInProcessDatabaseType(connType)) {
/*
* @todo - fredt - this should be the only static reference to
* a core class (apart form references to the Type package)
* from the jdbc package - we might make it dynamic
*/
sessionProxy = DatabaseManager.newSession(connType, database,
user, password, props, null, zoneSeconds);
} else if (DatabaseURL.S_HSQL.equals(connType)
|| DatabaseURL.S_HSQLS.equals(connType)) {
sessionProxy = new ClientConnection(host, port, path,
database, isTLS, isTLSWrapper, user, password, zoneSeconds);
isNetConn = true;
} else if (DatabaseURL.S_HTTP.equals(connType)
|| DatabaseURL.S_HTTPS.equals(connType)) {
sessionProxy = new ClientConnectionHTTP(host, port, path,
database, isTLS, isTLSWrapper, user, password, zoneSeconds);
isNetConn = true;
} else { // alias: type not yet implemented
throw JDBCUtil.invalidArgument(connType);
}
sessionProxy.setJDBCConnection(this);
connProperties = props;
clientProperties = sessionProxy.getClientProperties();
setLocalVariables();
} catch (HsqlException e) {
throw JDBCUtil.sqlException(e);
}
}
/**
* Constructs an INTERNAL
Connection
,
* using the specified {@link org.hsqldb.SessionInterface
* SessionInterface}.
*
* This constructor is called only on behalf of an existing
* Session
(the internal parallel of a
* Connection
), to be used as a parameter to a SQL
* function or stored procedure that needs to execute in the context
* of that Session
.
*
* When a Java SQL function or stored procedure is called and its
* first parameter is of type Connection
, HSQLDB
* automatically notices this and constructs an INTERNAL
* Connection
using the current Session
.
* HSQLDB then passes this Connection
in the first
* parameter position, moving any other parameter values
* specified in the SQL statement to the right by one position.
*
*
* To read more about this, see
* {@link org.hsqldb.Routine Routine}.
*
* Notes:
*
* Starting with HSQLDB 1.7.2, INTERNAL
connections are not
* closed by a call to close() or by a SQL DISCONNECT.
*
* For HSQLDB developers not involved with writing database
* internals, this change only applies to connections obtained
* automatically from the database as the first parameter to
* Java stored procedures and functions. This is mainly an issue
* to developers writing custom SQL function and stored procedure
* libraries for HSQLDB. Presently, it is recommended that SQL function and
* stored procedure code avoid depending on closing or issuing a
* DISCONNECT on a connection obtained in this manner.
*
* @param c the Session requesting the construction of this
* Connection
* @exception HsqlException never (reserved for future use);
* @see org.hsqldb.Routine
*/
public JDBCConnection(SessionInterface c) {
// PRE: SessionInterface is non-null
isInternal = true;
sessionProxy = c;
}
/**
* Constructor for use with connection pooling and XA.
*
* @param c the connection
* @param eventListener the listener
*/
public JDBCConnection(JDBCConnection c,
JDBCConnectionEventListener eventListener) {
sessionProxy = c.sessionProxy;
connProperties = c.connProperties;
clientProperties = c.clientProperties;
isPooled = true;
poolEventListener = eventListener;
setLocalVariables();
}
private void setLocalVariables() {
if (connProperties == null) {
return;
}
isCloseResultSet = connProperties.isPropertyTrue(
HsqlDatabaseProperties.url_close_result, false);
isUseColumnName = connProperties.isPropertyTrue(
HsqlDatabaseProperties.url_get_column_name, true);
isEmptyBatchAllowed = connProperties.isPropertyTrue(
HsqlDatabaseProperties.url_allow_empty_batch, false);
isTranslateTTIType = clientProperties.isPropertyTrue(
HsqlDatabaseProperties.jdbc_translate_tti_types, true);
isStoreLiveObject = clientProperties.isPropertyTrue(
HsqlDatabaseProperties.sql_live_object, false);
if (isStoreLiveObject) {
String connType = connProperties.getProperty("connection_type");
if(!DatabaseURL.S_MEM.equals(connType))
isStoreLiveObject = false;
}
}
synchronized int getSavepointID() {
return savepointIDSequence++;
}
/**
* Retrieves this connection's JDBC url.
*
* This method is in support of the JDBCDatabaseMetaData.getURL() method.
* @return the database connection url with which this object was
* constructed
* @throws SQLException if this connection is closed
*/
synchronized String getURL() throws SQLException {
checkClosed();
return isInternal ? sessionProxy.getInternalConnectionURL()
: connProperties.getProperty("url");
}
/**
* An internal check for closed connections.
*
* @throws SQLException when the connection is closed
*/
synchronized void checkClosed() throws SQLException {
if (isClosed) {
throw JDBCUtil.connectionClosedException();
}
}
/**
* Adds another SQLWarning to this Connection object's warning chain.
*
* @param w the SQLWarning to add to the chain
*/
void addWarning(SQLWarning w) {
// PRE: w is never null
synchronized (rootWarning_mutex) {
if (rootWarning == null) {
rootWarning = w;
} else {
rootWarning.setNextWarning(w);
}
}
}
/**
* Sets the warning chain
*/
void setWarnings(SQLWarning w) {
synchronized (rootWarning_mutex) {
rootWarning = w;
}
}
/**
* Resets this connection so it can be used again. Used when connections are
* returned to a connection pool.
*
* @throws SQLException if a database access error occurs
*/
public void reset() throws SQLException {
try {
incarnation++;
this.sessionProxy.resetSession();
} catch (HsqlException e) {
throw JDBCUtil.sqlException(ErrorCode.X_08006, e.getMessage(), e);
}
}
/**
* Completely closes a pooled connection
*/
public void closeFully() {
try {
close();
} catch (Throwable t) {
//
}
try {
if (sessionProxy != null) {
sessionProxy.close();
sessionProxy = null;
}
} catch (Throwable t) {
//
}
}
/**
* provides cross-package access to the proprietary (i.e. non-JDBC)
* HSQLDB session interface.
*
* @return the underlying sessionProxy for this connection
*/
public SessionInterface getSession() {
return sessionProxy;
}
/**
* is called from within nativeSQL when the start of an JDBC escape sequence is encountered
*/
private int onStartEscapeSequence(String sql, StringBuilder sb,
int i) throws SQLException {
sb.append(' ');
i++;
i = StringUtil.skipSpaces(sql, i);
if (sql.regionMatches(true, i, "fn ", 0, 3)
|| sql.regionMatches(true, i, "oj ", 0, 3)) {
i += 2;
} else if (sql.regionMatches(true, i, "ts ", 0, 3)) {
sb.append("TIMESTAMP");
i += 2;
} else if (sql.regionMatches(true, i, "d ", 0, 2)) {
sb.append("DATE");
i++;
} else if (sql.regionMatches(true, i, "t ", 0, 2)) {
sb.append("TIME");
i++;
} else if (sql.regionMatches(true, i, "call ", 0, 5)) {
sb.append("CALL");
i += 4;
} else if (sql.regionMatches(true, i, "?= call ", 0, 8)) {
sb.append("CALL");
i += 7;
} else if (sql.regionMatches(true, i, "? = call ", 0, 8)) {
sb.append("CALL");
i += 8;
} else if (sql.regionMatches(true, i, "escape ", 0, 7)) {
i += 6;
} else {
i--;
throw JDBCUtil.sqlException(ErrorCode.JDBC_CONNECTION_NATIVE_SQL,
sql.substring(i));
}
return i;
}
}