org.h2.Driver Maven / Gradle / Ivy
/*
* Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.DriverPropertyInfo;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Logger;
import org.h2.engine.Constants;
import org.h2.jdbc.JdbcConnection;
import org.h2.message.DbException;
import org.h2.upgrade.DbUpgrade;
/**
* The database driver. An application should not use this class directly. The
* only thing the application needs to do is load the driver. This can be done
* using Class.forName. To load the driver and open a database connection, use
* the following code:
*
*
* Class.forName("org.h2.Driver");
* Connection conn = DriverManager.getConnection(
* "jdbc:h2:˜/test", "sa", "sa");
*
*/
public class Driver implements java.sql.Driver, JdbcDriverBackwardsCompat {
private static final Driver INSTANCE = new Driver();
private static final String DEFAULT_URL = "jdbc:default:connection";
private static final ThreadLocal DEFAULT_CONNECTION =
new ThreadLocal<>();
private static volatile boolean registered;
static {
load();
}
/**
* Open a database connection.
* This method should not be called by an application.
* Instead, the method DriverManager.getConnection should be used.
*
* @param url the database URL
* @param info the connection properties
* @return the new connection or null if the URL is not supported
*/
@Override
public Connection connect(String url, Properties info) throws SQLException {
try {
if (info == null) {
info = new Properties();
}
if (!acceptsURL(url)) {
return null;
}
if (url.equals(DEFAULT_URL)) {
return DEFAULT_CONNECTION.get();
}
Connection c = DbUpgrade.connectOrUpgrade(url, info);
if (c != null) {
return c;
}
return new JdbcConnection(url, info);
} catch (Exception e) {
throw DbException.toSQLException(e);
}
}
/**
* Check if the driver understands this URL.
* This method should not be called by an application.
*
* @param url the database URL
* @return if the driver understands the URL
*/
@Override
public boolean acceptsURL(String url) {
if (url != null) {
if (url.startsWith(Constants.START_URL)) {
return true;
} else if (url.equals(DEFAULT_URL)) {
return DEFAULT_CONNECTION.get() != null;
}
}
return false;
}
/**
* Get the major version number of the driver.
* This method should not be called by an application.
*
* @return the major version number
*/
@Override
public int getMajorVersion() {
return Constants.VERSION_MAJOR;
}
/**
* Get the minor version number of the driver.
* This method should not be called by an application.
*
* @return the minor version number
*/
@Override
public int getMinorVersion() {
return Constants.VERSION_MINOR;
}
/**
* Get the list of supported properties.
* This method should not be called by an application.
*
* @param url the database URL
* @param info the connection properties
* @return a zero length array
*/
@Override
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) {
return new DriverPropertyInfo[0];
}
/**
* Check if this driver is compliant to the JDBC specification.
* This method should not be called by an application.
*
* @return true
*/
@Override
public boolean jdbcCompliant() {
return true;
}
/**
* [Not supported]
*/
@Override
public Logger getParentLogger() {
return null;
}
/**
* INTERNAL
*/
public static synchronized Driver load() {
try {
if (!registered) {
registered = true;
DriverManager.registerDriver(INSTANCE);
}
} catch (SQLException e) {
DbException.traceThrowable(e);
}
return INSTANCE;
}
/**
* INTERNAL
*/
public static synchronized void unload() {
try {
if (registered) {
registered = false;
DriverManager.deregisterDriver(INSTANCE);
}
} catch (SQLException e) {
DbException.traceThrowable(e);
}
}
/**
* INTERNAL
* Sets, on a per-thread basis, the default-connection for
* user-defined functions.
*/
public static void setDefaultConnection(Connection c) {
if (c == null) {
DEFAULT_CONNECTION.remove();
} else {
DEFAULT_CONNECTION.set(c);
}
}
/**
* INTERNAL
*/
public static void setThreadContextClassLoader(Thread thread) {
// Apache Tomcat: use the classloader of the driver to avoid the
// following log message:
// org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
// SEVERE: The web application appears to have started a thread named
// ... but has failed to stop it.
// This is very likely to create a memory leak.
try {
thread.setContextClassLoader(Driver.class.getClassLoader());
} catch (Throwable t) {
// ignore
}
}
}