001: /* Copyright (c) 2001-2005, The HSQL Development Group
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the HSQL Development Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package org.hsqldb;
032:
033: import java.sql.Connection;
034: import java.sql.Driver;
035: import java.sql.DriverManager;
036: import java.sql.DriverPropertyInfo;
037: import java.sql.SQLException;
038: import java.util.Properties;
039:
040: import org.hsqldb.jdbc.jdbcConnection;
041: import org.hsqldb.persist.HsqlDatabaseProperties;
042: import org.hsqldb.persist.HsqlProperties;
043:
044: // fredt@users 20011220 - patch 1.7.0 by fredt
045: // new version numbering scheme
046: // fredt@users 20020320 - patch 1.7.0 - JDBC 2 support and error trapping
047: // JDBC 2 methods can now be called from jdk 1.1.x - see javadoc comments
048: // fredt@users 20030528 - patch 1.7.2 suggested by Gerhard Hiller - support for properties in URL
049:
050: /**
051: * The following comments are from the http://ldbc.sourceforge.net project.
052: * These are the issues with HSQLDB JDBC implementation that are currently
053: * not resolved. Other issues stated there have been resolved in 1.8.0.
054: *
055: * Time format error: the following statement should work, but throws an exception:
056: * CREATE TABLE Test ( ID INT , Current DATETIME )
057: * insert into test values(1,'2002-01-01 0:0:0.0')
058: * This works:
059: * insert into test values(1,'2002-01-01 00:00:00.0')
060: *
061: * ABS(4) returns data type DECIMAL, should return data type INTEGER
062: *
063: * Should throw a exception if PreparedStatement.setObject(1,null) is called.
064: * See also JDBC API Tutorial and Reference, Second Edition,
065: * page 544, 24.1.5 Sending JDBC NULL as an IN parameter
066: *
067: * Statement / PreparedStatement setMaxFieldSize is ignored.
068: *
069: * The database should support at least Connection.TRANSACTION_READ_COMMITTED.
070: * Currently, only TRANSACTION_READ_UNCOMMITTED is supported.
071: *
072: * Statement.getQueryTimeout doesn't return the value set before.
073: *
074: * When autocommit is on, executing a query on a statement is
075: * supposed to close the old resultset. This is not implemented.
076: */
077:
078: /**
079: * Each JDBC driver must supply a class that implements the Driver
080: * interface. <p>
081: *
082: * The Java SQL framework allows for multiple database drivers. <p>
083: *
084: * The DriverManager will try to load as many drivers as it can find and
085: * then for any given connection request, it will ask each driver in turn
086: * to try to connect to the target URL. <p>
087: *
088: * The application developer will normally not need
089: * to call any function of the Driver directly. All required calls are made
090: * by the DriverManager. <p>
091: *
092: * <!-- start release-specific documentation -->
093: * <div class="ReleaseSpecificDocumentation">
094: * <h3>HSQLDB-Specific Information:</h3> <p>
095: * When the HSQL Database Engine Driver class is loaded, it creates an
096: * instance of itself and register it with the DriverManager. This means
097: * that a user can load and register the HSQL Database Engine driver by
098: * calling <pre>
099: * <code>Class.forName("org.hsqldb.jdbcDriver")</code> </pre> For more
100: * information about how to connect to a HSQL Database Engine database,
101: * please see jdbcConnection. </font><p>
102: *
103: * As of version 1.7.0 all JDBC 2 methods can be
104: * called with jdk 1.1.x. Some of these method calls require int values
105: * that are defined in JDBC 2 version of ResultSet. These values are
106: * defined in the jdbcResultSet class when it is compiled with jdk 1.1.x.
107: * When using the JDBC 2 methods that require those values as parameters or
108: * return one of those values, refer to them as follows: (The code will not
109: * be compatible with other JDBC 2 driver, which require ResultSet to be
110: * used instead of jdbcResultSet) (fredt@users)<p>
111: * </div> <!-- end release-specific documentation -->
112: *
113: * jdbcResultSet.FETCH_FORWARD<br>
114: * jdbcResultSet.TYPE_FORWARD_ONLY<br>
115: * jdbcResultSet TYPE_SCROLL_INSENSITIVE<br>
116: * jdbcResultSet.CONCUR_READ_ONLY</font><p>
117: *
118: *
119: * @see jdbcConnection
120: */
121: public class jdbcDriver implements Driver {
122:
123: /**
124: * Attempts to make a database connection to the given URL. The driver
125: * returns "null" if it realizes it is the wrong kind of driver to
126: * connect to the given URL. This will be common, as when the JDBC
127: * driver manager is asked to connect to a given URL it passes the URL
128: * to each loaded driver in turn.<p>
129: *
130: * The driver raises a SQLException if it is the right driver to
131: * connect to the given URL, but has trouble connecting to the
132: * database.<p>
133: *
134: * The java.util.Properties argument can be used to passed arbitrary
135: * string tag/value pairs as connection arguments.<p>
136: *
137: * <!-- start release-specific documentation -->
138: * <div class="ReleaseSpecificDocumentation">
139: * <h3>HSQLDB-Specific Information:</h3> <p>
140: * For HSQL Database Engine, at least "user" and
141: * "password" properties must be included in the Properties. From
142: * version 1.7.1 two optional properties are supported:<p>
143: * <code>get_column_name</code> if set to false, a
144: * ResultSetMetaData.getColumnName() call will return the user defined
145: * label instead of the column name.
146: * <code>strict_md</code> if set to true, some ResultSetMetaData methods
147: * return more strict values for compatibility reasons.
148: * </div> <!-- end release-specific documentation -->
149: *
150: * @param url the URL of the database to which to connect
151: * @param info a list of arbitrary string tag/value pairs as connection
152: * arguments. Normally at least a "user" and "password" property
153: * should be included.
154: * @return a <code>Connection</code> object that represents a
155: * connection to the URL
156: * @exception SQLException if a database access error occurs
157: */
158: public Connection connect(String url, Properties info)
159: throws SQLException {
160: return getConnection(url, info);
161: }
162:
163: public static Connection getConnection(String url, Properties info)
164: throws SQLException {
165:
166: HsqlProperties props = DatabaseURL.parseURL(url, true);
167:
168: if (props == null) {
169:
170: // supposed to be an HSQLDB driver url but has errors
171: throw new SQLException(Trace
172: .getMessage(Trace.INVALID_JDBC_ARGUMENT));
173: } else if (props.isEmpty()) {
174:
175: // is not an HSQLDB driver url
176: return null;
177: }
178:
179: props.addProperties(info);
180:
181: return new jdbcConnection(props);
182: }
183:
184: /**
185: * Returns true if the driver thinks that it can open a connection to
186: * the given URL. Typically drivers will return true if they understand
187: * the subprotocol specified in the URL and false if they don't.
188: *
189: * @param url the URL of the database
190: * @return true if this driver can connect to the given URL
191: */
192:
193: // fredt@users - patch 1.7.0 - allow mixedcase url's
194: public boolean acceptsURL(String url) {
195:
196: return url != null
197: && url.regionMatches(true, 0, DatabaseURL.S_URL_PREFIX,
198: 0, DatabaseURL.S_URL_PREFIX.length());
199: }
200:
201: /**
202: * Gets information about the possible properties for this driver. <p>
203: *
204: * The getPropertyInfo method is intended to allow a generic GUI tool
205: * to discover what properties it should prompt a human for in order to
206: * get enough information to connect to a database. Note that depending
207: * on the values the human has supplied so far, additional values may
208: * become necessary, so it may be necessary to iterate though several
209: * calls to getPropertyInfo.<p>
210: *
211: * <!-- start release-specific documentation -->
212: * <div class="ReleaseSpecificDocumentation">
213: * <h3>HSQLDB-Specific Information:</h3> <p>
214: * HSQLDB 1.7.2 uses the values submitted in info to set the value for
215: * each DriverPropertyInfo object returned. It does not use the default
216: * value that it would use for the property if the value is null.
217: * </div> <!-- end release-specific documentation -->
218: *
219: * @param url the URL of the database to which to connect
220: * @param info a proposed list of tag/value pairs that will be sent on
221: * connect open
222: * @return an array of DriverPropertyInfo objects describing possible
223: * properties. This array may be an empty array if no properties
224: * are required.
225: */
226: public DriverPropertyInfo[] getPropertyInfo(String url,
227: Properties info) {
228:
229: String[] choices = new String[] { "true", "false" };
230: DriverPropertyInfo[] pinfo = new DriverPropertyInfo[6];
231: DriverPropertyInfo p;
232:
233: p = new DriverPropertyInfo("user", null);
234: p.value = info.getProperty("user");
235: p.required = true;
236: pinfo[0] = p;
237: p = new DriverPropertyInfo("password", null);
238: p.value = info.getProperty("password");
239: p.required = true;
240: pinfo[1] = p;
241: p = new DriverPropertyInfo("get_column_name", null);
242: p.value = info.getProperty("get_column_name", "true");
243: p.required = false;
244: p.choices = choices;
245: pinfo[2] = p;
246: p = new DriverPropertyInfo("ifexists", null);
247: p.value = info.getProperty("ifexists");
248: p.required = false;
249: p.choices = choices;
250: pinfo[3] = p;
251: p = new DriverPropertyInfo("default_schema", null);
252: p.value = info.getProperty("default_schema");
253: p.required = false;
254: p.choices = choices;
255: pinfo[4] = p;
256: p = new DriverPropertyInfo("shutdown", null);
257: p.value = info.getProperty("shutdown");
258: p.required = false;
259: p.choices = choices;
260: pinfo[5] = p;
261:
262: return pinfo;
263: }
264:
265: /**
266: * Gets the driver's major version number.
267: *
268: * @return this driver's major version number
269: */
270: public int getMajorVersion() {
271: return HsqlDatabaseProperties.MAJOR;
272: }
273:
274: /**
275: * Gets the driver's minor version number.
276: *
277: * @return this driver's minor version number
278: */
279: public int getMinorVersion() {
280: return HsqlDatabaseProperties.MINOR;
281: }
282:
283: /**
284: * Reports whether this driver is a genuine JDBC COMPLIANT<sup><font
285: * size=-2>TM</font> </sup> driver. A driver may only report true here
286: * if it passes the JDBC compliance tests; otherwise it is required to
287: * return false. JDBC compliance requires full support for the JDBC API
288: * and full support for SQL 92 Entry Level. It is expected that JDBC
289: * compliant drivers will be available for all the major commercial
290: * databases. <p>
291: *
292: * <!-- start release-specific documentation -->
293: * <div class="ReleaseSpecificDocumentation">
294: * <h3>HSQLDB-Specific Information:</h3> <p>
295: * HSQL Database Engine currently does not yet
296: * support all required SQL 92 Entry Level functionality and thus
297: * returns false. It looks like other drivers return true but do not
298: * support all features.<p>
299: * </div> <!-- end release-specific documentation -->
300: *
301: * This method is not intended to encourage the development of non-JDBC
302: * compliant drivers, but is a recognition of the fact that some
303: * vendors are interested in using the JDBC API and framework for
304: * lightweight databases that do not support full database
305: * functionality, or for special databases such as document information
306: * retrieval where a SQL implementation may not be feasible.
307: *
308: * @return Description of the Return Value
309: */
310: public boolean jdbcCompliant() {
311:
312: /** @todo fredt - we should aim to be able to report true */
313: return false;
314: }
315:
316: static {
317: try {
318: DriverManager.registerDriver(new jdbcDriver());
319: } catch (Exception e) {
320: }
321: }
322: }
|