diff --git a/jOOQ/pom.xml b/jOOQ/pom.xml index 786a0711ed..a168dcc97b 100644 --- a/jOOQ/pom.xml +++ b/jOOQ/pom.xml @@ -197,13 +197,6 @@ provided true - - com.oracle - ojdbc6 - 11.1.0.7.0 - provided - true - junit junit diff --git a/jOOQ/src/main/java/org/jooq/impl/ArrayRecordImpl.java b/jOOQ/src/main/java/org/jooq/impl/ArrayRecordImpl.java index e5ca33d5db..19199375ba 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ArrayRecordImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ArrayRecordImpl.java @@ -35,6 +35,9 @@ */ package org.jooq.impl; +import static org.jooq.impl.Util.getDriverConnection; +import static org.jooq.tools.reflect.Reflect.on; + import java.lang.reflect.Array; import java.sql.SQLException; import java.util.ArrayList; @@ -50,7 +53,6 @@ import org.jooq.DataType; import org.jooq.SQLDialect; import org.jooq.exception.SQLDialectNotSupportedException; import org.jooq.tools.Convert; -import org.jooq.util.oracle.OracleUtils; /** * A common base class for Oracle ARRAY types @@ -180,8 +182,10 @@ public class ArrayRecordImpl extends AbstractStore implements ArrayRecord< SQLDialect dialect = getConfiguration().getDialect(); switch (dialect) { - case ORACLE: - return OracleUtils.createArray(getConfiguration().getConnection(), this); + case ORACLE: { + // [#1161] Use reflection to avoid compile-time on ojdbc + return on(getDriverConnection(getConfiguration())).call("createARRAY", getName(), get()).get(); + } default: throw new SQLDialectNotSupportedException( diff --git a/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java b/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java index 509d2e0fd8..6d69911775 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java +++ b/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java @@ -74,6 +74,10 @@ class ConnectionProxy implements Connection { this.settings = settings; } + final Connection getDelegate() { + return delegate; + } + // ------------------------------------------------------------------------ // XXX Creation of PreparedStatements // ------------------------------------------------------------------------ diff --git a/jOOQ/src/main/java/org/jooq/impl/Factory.java b/jOOQ/src/main/java/org/jooq/impl/Factory.java index 4e28f6f1ea..f7e1c107cf 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Factory.java +++ b/jOOQ/src/main/java/org/jooq/impl/Factory.java @@ -244,7 +244,15 @@ public class Factory implements FactoryOperations { */ @Override public final Connection getConnection() { - return (connection == null ? null : new ConnectionProxy(connection, settings)); + if (connection == null) { + return null; + } + else if (connection.getClass() == ConnectionProxy.class) { + return connection; + } + else { + return new ConnectionProxy(connection, settings); + } } /** diff --git a/jOOQ/src/main/java/org/jooq/impl/Util.java b/jOOQ/src/main/java/org/jooq/impl/Util.java index d7d9b270a0..d912f35258 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Util.java +++ b/jOOQ/src/main/java/org/jooq/impl/Util.java @@ -42,6 +42,7 @@ import static org.jooq.tools.StringUtils.leftPad; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -93,7 +94,7 @@ final class Util { /** * Create a new Oracle-style VARRAY {@link ArrayRecord} */ - static > R newArrayRecord(Class type, Configuration configuration) { + static final > R newArrayRecord(Class type, Configuration configuration) { try { return type.getConstructor(Configuration.class).newInstance(configuration); } @@ -108,28 +109,28 @@ final class Util { /** * Create a new record */ - static R newRecord(Class type) { + static final R newRecord(Class type) { return newRecord(type, null); } /** * Create a new record */ - static R newRecord(Class type, FieldProvider provider) { + static final R newRecord(Class type, FieldProvider provider) { return newRecord(type, provider, null); } /** * Create a new record */ - static R newRecord(Type type) { + static final R newRecord(Type type) { return newRecord(type, null); } /** * Create a new record */ - static R newRecord(Type type, Configuration configuration) { + static final R newRecord(Type type, Configuration configuration) { return newRecord(type.getRecordType(), type, configuration); } @@ -137,7 +138,7 @@ final class Util { * Create a new record */ @SuppressWarnings("unchecked") - static R newRecord(Class type, FieldProvider provider, Configuration configuration) { + static final R newRecord(Class type, FieldProvider provider, Configuration configuration) { try { R result; @@ -301,7 +302,7 @@ final class Util { /** * Create SQL */ - static void toSQLReference(RenderContext context, String sql, List> bindings) { + static final void toSQLReference(RenderContext context, String sql, List> bindings) { // Replace bind variables by their associated bind values if (context.inline()) { @@ -352,7 +353,7 @@ final class Util { /** * Create {@link Param} objects from bind values */ - static List> bindings(Object... bindings) { + static final List> bindings(Object... bindings) { // [#724] When bindings is null, this is probably due to API-misuse // The user probably meant new Object[] { null } if (bindings == null) { @@ -375,7 +376,7 @@ final class Util { * * @see #toSQLReference(RenderContext, String, List) */ - static void toSQLReferenceWithParentheses(RenderContext context, String sql, List> bindings) { + static final void toSQLReferenceWithParentheses(RenderContext context, String sql, List> bindings) { context.sql("("); toSQLReference(context, sql, bindings); context.sql(")"); @@ -385,7 +386,7 @@ final class Util { * Render a list of names of the NamedQueryParts contained in * this list. */ - static void toSQLNames(RenderContext context, Collection list) { + static final void toSQLNames(RenderContext context, Collection list) { String separator = ""; for (NamedQueryPart part : list) { @@ -398,7 +399,7 @@ final class Util { /** * Combine a field with an array of fields */ - static Field[] combine(Field field, Field... fields) { + static final Field[] combine(Field field, Field... fields) { if (fields == null) { return new Field[] { field }; } @@ -414,7 +415,7 @@ final class Util { /** * Combine a field with an array of fields */ - static Field[] combine(Field field1, Field field2, Field... fields) { + static final Field[] combine(Field field1, Field field2, Field... fields) { if (fields == null) { return new Field[] { field1, field2 }; } @@ -431,7 +432,7 @@ final class Util { /** * Combine a field with an array of fields */ - static Field[] combine(Field field1, Field field2, Field field3, Field... fields) { + static final Field[] combine(Field field1, Field field2, Field field3, Field... fields) { if (fields == null) { return new Field[] { field1, field2, field3 }; } @@ -448,7 +449,7 @@ final class Util { /** * Translate a {@link SQLException} to a {@link DataAccessException} */ - static DataAccessException translate(String task, String sql, SQLException e) { + static final DataAccessException translate(String task, String sql, SQLException e) { String message = task + "; SQL [" + sql + "]; " + e.getMessage(); return new DataAccessException(message, e); } @@ -456,7 +457,7 @@ final class Util { /** * Safely close a statement */ - static void safeClose(Statement statement) { + static final void safeClose(Statement statement) { if (statement != null) { try { statement.close(); @@ -468,7 +469,7 @@ final class Util { /** * Safely close a result set */ - static void safeClose(ResultSet resultSet) { + static final void safeClose(ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); @@ -480,7 +481,7 @@ final class Util { /** * Safely close a cursor */ - static void safeClose(Cursor cursor) { + static final void safeClose(Cursor cursor) { if (cursor != null) { try { cursor.close(); @@ -492,15 +493,41 @@ final class Util { /** * Safely close a result set and / or a statement */ - static void safeClose(ResultSet resultSet, PreparedStatement statement) { + static final void safeClose(ResultSet resultSet, PreparedStatement statement) { safeClose(resultSet); safeClose(statement); } + /** + * Extract an underlying connection + */ + static final Connection getDriverConnection(Configuration configuration) { + if (configuration != null) { + Connection connection = configuration.getConnection(); + + if (connection != null) { + + // If the connection is wrapped by jOOQ, extract the underlying + // connection + if (connection.getClass() == ConnectionProxy.class) { + connection = ((ConnectionProxy) connection).getDelegate(); + } + + // [#1157] TODO: If jOOQ's extended tracing / logging feature + // allows for further wrapping a connection, this must be + // treated here... + + return connection; + } + } + + throw new DataAccessException("Cannot get a JDBC driver connection from configuration: " + configuration); + } + /** * Check if JPA classes can be loaded. This is only done once per JVM! */ - private static boolean isJPAAvailable() { + private static final boolean isJPAAvailable() { if (isJPAAvailable == null) { try { Class.forName(Column.class.getName()); @@ -764,7 +791,7 @@ final class Util { * Map a {@link Schema} according to the configured {@link org.jooq.SchemaMapping} */ @SuppressWarnings("deprecation") - static Schema getMappedSchema(Configuration configuration, Schema schema) { + static final Schema getMappedSchema(Configuration configuration, Schema schema) { if (configuration.getSchemaMapping() != null) { return configuration.getSchemaMapping().map(schema); } @@ -777,7 +804,7 @@ final class Util { * Map a {@link Table} according to the configured {@link org.jooq.SchemaMapping} */ @SuppressWarnings("deprecation") - static Table getMappedTable(Configuration configuration, Table table) { + static final Table getMappedTable(Configuration configuration, Table table) { if (configuration.getSchemaMapping() != null) { return configuration.getSchemaMapping().map(table); } @@ -789,7 +816,7 @@ final class Util { /** * Wrap a piece of SQL code in parentheses, if not wrapped already */ - static String wrapInParentheses(String sql) { + static final String wrapInParentheses(String sql) { if (sql.startsWith("(")) { return sql; } @@ -801,14 +828,14 @@ final class Util { /** * Expose the internal API of an {@link Attachable} */ - static AttachableInternal internal(Attachable part) { + static final AttachableInternal internal(Attachable part) { return part.internalAPI(AttachableInternal.class); } /** * Expose the internal API of a {@link QueryPart} */ - static QueryPartInternal internal(QueryPart part) { + static final QueryPartInternal internal(QueryPart part) { return part.internalAPI(QueryPartInternal.class); } @@ -816,7 +843,7 @@ final class Util { * Return a non-negative hash code for a {@link QueryPart}, taking into * account FindBugs' RV_ABSOLUTE_VALUE_OF_HASHCODE pattern */ - static int hash(Object object) { + static final int hash(Object object) { return 0x7FFFFFF & object.hashCode(); } @@ -827,7 +854,7 @@ final class Util { /** * Get the statement type from the settings */ - static StatementType getStatementType(Settings settings) { + static final StatementType getStatementType(Settings settings) { if (settings != null) { Execution execution = settings.getExecution(); @@ -856,7 +883,7 @@ final class Util { * @param value the byte array * @return the hex encoded string */ - static String convertBytesToHex(byte[] value) { + static final String convertBytesToHex(byte[] value) { return convertBytesToHex(value, value.length); } @@ -867,7 +894,7 @@ final class Util { * @param len the number of bytes to encode * @return the hex encoded string */ - static String convertBytesToHex(byte[] value, int len) { + static final String convertBytesToHex(byte[] value, int len) { char[] buff = new char[len + len]; char[] hex = HEX; for (int i = 0; i < len; i++) { @@ -881,7 +908,7 @@ final class Util { /** * Postgres uses octals instead of hex encoding */ - static String convertBytesToPostgresOctal(byte[] binary) { + static final String convertBytesToPostgresOctal(byte[] binary) { StringBuilder sb = new StringBuilder(); for (byte b : binary) { diff --git a/jOOQ/src/main/java/org/jooq/util/oracle/OracleUtils.java b/jOOQ/src/main/java/org/jooq/util/oracle/OracleUtils.java deleted file mode 100644 index ec2fd2c1a2..0000000000 --- a/jOOQ/src/main/java/org/jooq/util/oracle/OracleUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2009-2011, Lukas Eder, lukas.eder@gmail.com - * All rights reserved. - * - * This software is licensed to you under the Apache License, Version 2.0 - * (the "License"); You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 "jOOQ" 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 THE COPYRIGHT OWNER 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.jooq.util.oracle; - -import java.sql.Array; -import java.sql.Connection; -import java.sql.SQLException; - -import oracle.sql.ARRAY; -import oracle.sql.ArrayDescriptor; - -import org.jooq.ArrayRecord; -import org.jooq.SQLDialect; - -/** - * Utility methods for use with {@link SQLDialect#ORACLE} - *

- * This class has a hidden dependency on the Oracle JDBC driver. Be sure that - * these classes and all of their dependencies are located on the classpath: - *

    - *
  • {@link ArrayDescriptor}
  • - *
  • {@link ARRAY}
  • - *
- * - * @author Lukas Eder - */ -public final class OracleUtils { - - /** - * Create an Oracle {@link ARRAY} - */ - public static Array createArray(Connection connection, ArrayRecord record) throws SQLException { - ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(record.getName(), connection); - return new ARRAY(descriptor, connection, record.get()); - } - - private OracleUtils() {} -}