/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
 * database integrations.
 *
 * For more information, please visit: http://www.jooq.org/licenses
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq.tools.jdbc;

// ...
import static org.jooq.SQLDialect.CUBRID;
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.DEFAULT;
import static org.jooq.SQLDialect.DERBY;
import static org.jooq.SQLDialect.FIREBIRD;
// ...
// ...
import static org.jooq.SQLDialect.H2;
// ...
import static org.jooq.SQLDialect.HSQLDB;
// ...
// ...
import static org.jooq.SQLDialect.MARIADB;
// ...
// ...
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.MYSQL;
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.POSTGRES;
// ...
// ...
// ...
// ...
// ...
// ...
// ...
import static org.jooq.SQLDialect.SQLITE;
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...
// ...

import java.io.Closeable;
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.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLInput;
import java.sql.SQLXML;
import java.sql.Statement;

// ...
import org.jooq.SQLDialect;
import org.jooq.tools.JooqLogger;

import org.jetbrains.annotations.NotNull;

JDBC-related utility methods.
Author:Lukas Eder
/** * JDBC-related utility methods. * * @author Lukas Eder */
public class JDBCUtils { private static final JooqLogger log = JooqLogger.getLogger(JDBCUtils.class);
"Guess" the SQLDialect from a Connection instance.

This method tries to guess the SQLDialect of a connection from the its connection URL as obtained by DatabaseMetaData.getURL(). If the dialect cannot be guessed from the URL (e.g. when using an JDBC-ODBC bridge), further actions may be implemented in the future.

See Also:
Returns:The appropriate SQLDialect or SQLDialect.DEFAULT if no dialect could be derived from the connection. Never null.
/** * "Guess" the {@link SQLDialect} from a {@link Connection} instance. * <p> * This method tries to guess the <code>SQLDialect</code> of a connection * from the its connection URL as obtained by * {@link DatabaseMetaData#getURL()}. If the dialect cannot be guessed from * the URL (e.g. when using an JDBC-ODBC bridge), further actions may be * implemented in the future. * * @return The appropriate {@link SQLDialect} or {@link SQLDialect#DEFAULT} * if no dialect could be derived from the connection. Never * <code>null</code>. * @see #dialect(String) */
@NotNull public static final SQLDialect dialect(Connection connection) { SQLDialect result = SQLDialect.DEFAULT; if (connection != null) { try { DatabaseMetaData m = connection.getMetaData(); String url = m.getURL(); int majorVersion = 0; int minorVersion = 0; // [#6814] Better play safe with JDBC API try { majorVersion = m.getDatabaseMajorVersion(); } catch (SQLException ignore) {} try { minorVersion = m.getDatabaseMinorVersion(); } catch (SQLException ignore) {} result = dialect(url, majorVersion, minorVersion); } catch (SQLException ignore) {} } if (result == SQLDialect.DEFAULT) { // If the dialect cannot be guessed from the URL, take some other // measures, e.g. by querying DatabaseMetaData.getDatabaseProductName() } return result; } @NotNull private static final SQLDialect dialect(String url, int majorVersion, int minorVersion) { SQLDialect dialect = dialect(url); // [#6814] If the driver can't report the version, fall back to the dialect family if (majorVersion == 0) return dialect; switch (dialect.family()) { case FIREBIRD: return firebirdDialect(majorVersion); case MARIADB: return mariadbDialect(majorVersion, minorVersion); case MYSQL: return mysqlDialect(majorVersion); case POSTGRES: return postgresDialect(majorVersion, minorVersion); } return dialect; } private static final SQLDialect postgresDialect(int majorVersion, int minorVersion) { return POSTGRES; } private static final SQLDialect mariadbDialect(int majorVersion, int minorVersion) { return MARIADB; } private static final SQLDialect mysqlDialect(int majorVersion) { return MYSQL; } private static final SQLDialect firebirdDialect(int majorVersion) { return FIREBIRD; }
"Guess" the SQLDialect from a connection URL.
Returns:The appropriate SQLDialect or SQLDialect.DEFAULT if no dialect could be derived from the connection. Never null.
/** * "Guess" the {@link SQLDialect} from a connection URL. * * @return The appropriate {@link SQLDialect} or {@link SQLDialect#DEFAULT} * if no dialect could be derived from the connection. Never * <code>null</code>. */
@NotNull public static final SQLDialect dialect(String url) { if (url == null) return DEFAULT; // The below list might not be accurate or complete. Feel free to // contribute fixes related to new / different JDBC driver configurations // [#6035] Third-party JDBC proxies (e.g. www.testcontainers.org) often work // by inserting their names into the JDBC URL, e.g. jdbc:tc:mysql://... // This is why we no longer check for a URL to start with jdbc:mysql: // but to simply contain :mysql: else if (url.contains(":cubrid:")) return CUBRID; else if (url.contains(":derby:")) return DERBY; else if (url.contains(":firebirdsql:")) return FIREBIRD; else if (url.contains(":h2:")) return H2; else if (url.contains(":hsqldb:")) return HSQLDB; else if (url.contains(":mariadb:")) return MARIADB; else if (url.contains(":mysql:") || url.contains(":google:")) return MYSQL; else if (url.contains(":postgresql:") || url.contains(":pgsql:")) return POSTGRES; else if (url.contains(":sqlite:") || url.contains(":sqldroid:")) return SQLITE; return DEFAULT; }
"Guess" the JDBC driver from a SQLDialect.
Returns:The appropriate JDBC driver class or "java.sql.Driver" if no driver class could be derived from the URL. Never null.
/** * "Guess" the JDBC driver from a {@link SQLDialect}. * * @return The appropriate JDBC driver class or * <code>"java.sql.Driver"</code> if no driver class could be * derived from the URL. Never <code>null</code>. */
@NotNull public static final String driver(SQLDialect dialect) { switch (dialect.family()) { case CUBRID: return "cubrid.jdbc.driver.CUBRIDDriver"; case DERBY: return "org.apache.derby.jdbc.ClientDriver"; case FIREBIRD: return "org.firebirdsql.jdbc.FBDriver"; case H2: return "org.h2.Driver"; case HSQLDB: return "org.hsqldb.jdbcDriver"; case MARIADB: return "org.mariadb.jdbc.Driver"; case MYSQL: return "com.mysql.cj.jdbc.Driver"; case POSTGRES: return "org.postgresql.Driver"; case SQLITE: return "org.sqlite.JDBC"; } return "java.sql.Driver"; }
"Guess" the JDBC driver from a connection URL.
Returns:The appropriate JDBC driver class or "java.sql.Driver" if no driver class could be derived from the URL. Never null.
/** * "Guess" the JDBC driver from a connection URL. * * @return The appropriate JDBC driver class or * <code>"java.sql.Driver"</code> if no driver class could be * derived from the URL. Never <code>null</code>. */
@NotNull public static final String driver(String url) { return driver(dialect(url).family()); }
Safely close a connection.

This method will silently ignore if connection is null, or if Connection.close() throws an exception.

/** * Safely close a connection. * <p> * This method will silently ignore if <code>connection</code> is * <code>null</code>, or if {@link Connection#close()} throws an exception. */
public static final void safeClose(Connection connection) { if (connection != null) { try { connection.close(); } catch (Exception ignore) {} } }
Safely close a statement.

This method will silently ignore if statement is null, or if Statement.close() throws an exception.

/** * Safely close a statement. * <p> * This method will silently ignore if <code>statement</code> is * <code>null</code>, or if {@link Statement#close()} throws an exception. */
public static final void safeClose(Statement statement) { if (statement != null) { try { statement.close(); } catch (Exception ignore) {} } }
Safely close a result set.

This method will silently ignore if resultSet is null, or if ResultSet.close() throws an exception.

/** * Safely close a result set. * <p> * This method will silently ignore if <code>resultSet</code> is * <code>null</code>, or if {@link ResultSet#close()} throws an exception. */
public static final void safeClose(ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (Exception ignore) {} } }
Safely close a result set and / or a statement.

This method will silently ignore if resultSet or statement is null, or if ResultSet.close() or Statement.close() throws an exception.

/** * Safely close a result set and / or a statement. * <p> * This method will silently ignore if <code>resultSet</code> or * <code>statement</code> is <code>null</code>, or if * {@link ResultSet#close()} or {@link Statement#close()} throws an * exception. */
public static final void safeClose(ResultSet resultSet, PreparedStatement statement) { safeClose(resultSet); safeClose(statement); }
Safely close a closeable.

This method will silently ignore if closeable is null, or if Closeable.close() throws an exception.

/** * Safely close a closeable. * <p> * This method will silently ignore if <code>closeable</code> is * <code>null</code>, or if {@link Closeable#close()} throws an exception. */
public static final void safeClose(Closeable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception ignore) {} } }
Safely close a closeable.

This method will silently ignore if closeable is null, or if AutoCloseable.close() throws an exception.

/** * Safely close a closeable. * <p> * This method will silently ignore if <code>closeable</code> is * <code>null</code>, or if {@link AutoCloseable#close()} throws an exception. */
public static final void safeClose(AutoCloseable closeable) { if (closeable != null) { try { closeable.close(); } catch (Exception ignore) {} } }
Safely free a blob.

This method will silently ignore if blob is null, or if Blob.free() throws an exception.

/** * Safely free a blob. * <p> * This method will silently ignore if <code>blob</code> is * <code>null</code>, or if {@link Blob#free()} throws an exception. */
public static final void safeFree(Blob blob) { if (blob != null) { try { blob.free(); } catch (Exception ignore) { log.warn("Error while freeing resource", ignore); } // [#3069] The free() method was added only in JDBC 4.0 / Java 1.6 catch (AbstractMethodError ignore) {} } }
Safely free a clob.

This method will silently ignore if clob is null, or if Clob.free() throws an exception.

/** * Safely free a clob. * <p> * This method will silently ignore if <code>clob</code> is * <code>null</code>, or if {@link Clob#free()} throws an exception. */
public static final void safeFree(Clob clob) { if (clob != null) { try { clob.free(); } catch (Exception ignore) { log.warn("Error while freeing resource", ignore); } // [#3069] The free() method was added only in JDBC 4.0 / Java 1.6 catch (AbstractMethodError ignore) {} } }
Safely free an XML object.

This method will silently ignore if xml is null, or if SQLXML.free() throws an exception.

/** * Safely free an XML object. * <p> * This method will silently ignore if <code>xml</code> is * <code>null</code>, or if {@link SQLXML#free()} throws an exception. */
public static final void safeFree(SQLXML xml) { if (xml != null) { try { xml.free(); } catch (Exception ignore) { log.warn("Error while freeing resource", ignore); } // [#3069] The free() method was added only in JDBC 4.0 / Java 1.6 catch (AbstractMethodError ignore) {} } }
Safely free an Array object.

This method will silently ignore if array is null, or if Array.free() throws an exception.

/** * Safely free an Array object. * <p> * This method will silently ignore if <code>array</code> is * <code>null</code>, or if {@link Array#free()} throws an exception. */
public static final void safeFree(Array array) { if (array != null) { try { array.free(); } catch (Exception ignore) { log.warn("Error while freeing resource", ignore); } // [#3069] The free() method was added only in JDBC 4.0 / Java 1.6 catch (AbstractMethodError ignore) {} } }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • stream – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the SQLInput.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param stream The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link SQLInput#wasNull()} is <code>true</code> */
public static final <T> T wasNull(SQLInput stream, T value) throws SQLException { return (value == null || stream.wasNull()) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • stream – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the SQLInput.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param stream The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link SQLInput#wasNull()} is <code>true</code> */
public static final <T extends Number> T wasNull(SQLInput stream, T value) throws SQLException { return (value == null || (value.intValue() == 0 && stream.wasNull())) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • stream – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the SQLInput.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param stream The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link SQLInput#wasNull()} is <code>true</code> */
public static final Boolean wasNull(SQLInput stream, Boolean value) throws SQLException { return (value == null || (value.booleanValue() == false && stream.wasNull())) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • rs – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the ResultSet.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param rs The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link ResultSet#wasNull()} is <code>true</code> */
public static final <T> T wasNull(ResultSet rs, T value) throws SQLException { return (value == null || rs.wasNull()) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • rs – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the ResultSet.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param rs The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link ResultSet#wasNull()} is <code>true</code> */
public static final <T extends Number> T wasNull(ResultSet rs, T value) throws SQLException { return (value == null || (value.intValue() == 0 && rs.wasNull())) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • rs – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the ResultSet.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param rs The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link ResultSet#wasNull()} is <code>true</code> */
public static final Boolean wasNull(ResultSet rs, Boolean value) throws SQLException { return (value == null || (value.booleanValue() == false && rs.wasNull())) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • statement – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the CallableStatement.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param statement The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link CallableStatement#wasNull()} is <code>true</code> */
public static final <T> T wasNull(CallableStatement statement, T value) throws SQLException { return (value == null || statement.wasNull()) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • statement – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the CallableStatement.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param statement The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link CallableStatement#wasNull()} is <code>true</code> */
public static final <T extends Number> T wasNull(CallableStatement statement, T value) throws SQLException { return (value == null || (value.intValue() == 0 && statement.wasNull())) ? null : value; }
Convenient way to check if a JDBC-originated record was null.

This is useful to check if primitive types obtained from the JDBC API were actually SQL NULL values.

Params:
  • statement – The data source from which a value was read
  • value – The value that was read
Returns:The value or null if the CallableStatement.wasNull() is true
/** * Convenient way to check if a JDBC-originated record was <code>null</code>. * <p> * This is useful to check if primitive types obtained from the JDBC API * were actually SQL NULL values. * * @param statement The data source from which a value was read * @param value The value that was read * @return The <code>value</code> or <code>null</code> if the * {@link CallableStatement#wasNull()} is <code>true</code> */
public static final Boolean wasNull(CallableStatement statement, Boolean value) throws SQLException { return (value == null || (value.booleanValue() == false && statement.wasNull())) ? null : value; }
No instances.
/** * No instances. */
private JDBCUtils() {} }