diff --git a/jOOQ-test/launch/jOOQOracleTest (No bind variables).launch b/jOOQ-test/launch/jOOQOracleTest (No bind variables).launch new file mode 100644 index 0000000000..c863635ea5 --- /dev/null +++ b/jOOQ-test/launch/jOOQOracleTest (No bind variables).launch @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jOOQ-test/launch/jOOQSQLServerTest (No bind variables).launch b/jOOQ-test/launch/jOOQSQLServerTest (No bind variables).launch new file mode 100644 index 0000000000..57b3ff934c --- /dev/null +++ b/jOOQ-test/launch/jOOQSQLServerTest (No bind variables).launch @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/SchemaAndMappingTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/SchemaAndMappingTests.java index e50d349ab2..ec0debe9f5 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/SchemaAndMappingTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/SchemaAndMappingTests.java @@ -124,8 +124,8 @@ extends BaseTest q = create(settings).select(TBook_TITLE()) @@ -165,8 +165,8 @@ extends BaseTest query = create(settings).select(TBook_TITLE()) @@ -269,8 +269,8 @@ extends BaseTest - diff --git a/jOOQ/src/main/java/org/jooq/conf/Execution.java b/jOOQ/src/main/java/org/jooq/conf/Execution.java index 2cd749371e..c36ca661d8 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Execution.java +++ b/jOOQ/src/main/java/org/jooq/conf/Execution.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @@ -38,29 +38,14 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "Execution", propOrder = { }) -public class Execution implements Serializable +public class Execution + implements Serializable { private final static long serialVersionUID = 205L; @XmlElement(defaultValue = "PREPARED_STATEMENT") protected StatementType statementType = StatementType.PREPARED_STATEMENT; - /** - * Default no-arg constructor - * - */ - public Execution() { - super(); - } - - /** - * Fully-initialising value constructor - * - */ - public Execution(final StatementType statementType) { - this.statementType = statementType; - } - /** * Gets the value of the statementType property. * diff --git a/jOOQ/src/main/java/org/jooq/conf/MappedSchema.java b/jOOQ/src/main/java/org/jooq/conf/MappedSchema.java index d36b4bca43..166a921a9f 100644 --- a/jOOQ/src/main/java/org/jooq/conf/MappedSchema.java +++ b/jOOQ/src/main/java/org/jooq/conf/MappedSchema.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @@ -44,7 +44,8 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "MappedSchema", propOrder = { }) -public class MappedSchema implements Serializable +public class MappedSchema + implements Serializable { private final static long serialVersionUID = 205L; @@ -55,24 +56,6 @@ public class MappedSchema implements Serializable @XmlElement(name = "table") protected List tables; - /** - * Default no-arg constructor - * - */ - public MappedSchema() { - super(); - } - - /** - * Fully-initialising value constructor - * - */ - public MappedSchema(final String input, final String output, final List tables) { - this.input = input; - this.output = output; - this.tables = tables; - } - /** * Gets the value of the input property. * diff --git a/jOOQ/src/main/java/org/jooq/conf/MappedTable.java b/jOOQ/src/main/java/org/jooq/conf/MappedTable.java index eb50c70bee..48c52fccad 100644 --- a/jOOQ/src/main/java/org/jooq/conf/MappedTable.java +++ b/jOOQ/src/main/java/org/jooq/conf/MappedTable.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @@ -39,7 +39,8 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "MappedTable", propOrder = { }) -public class MappedTable implements Serializable +public class MappedTable + implements Serializable { private final static long serialVersionUID = 205L; @@ -48,23 +49,6 @@ public class MappedTable implements Serializable @XmlElement(required = true) protected String output; - /** - * Default no-arg constructor - * - */ - public MappedTable() { - super(); - } - - /** - * Fully-initialising value constructor - * - */ - public MappedTable(final String input, final String output) { - this.input = input; - this.output = output; - } - /** * Gets the value of the input property. * diff --git a/jOOQ/src/main/java/org/jooq/conf/RenderMapping.java b/jOOQ/src/main/java/org/jooq/conf/RenderMapping.java index 110cf1c959..76306c00fe 100644 --- a/jOOQ/src/main/java/org/jooq/conf/RenderMapping.java +++ b/jOOQ/src/main/java/org/jooq/conf/RenderMapping.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @@ -43,7 +43,8 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "RenderMapping", propOrder = { }) -public class RenderMapping implements Serializable +public class RenderMapping + implements Serializable { private final static long serialVersionUID = 205L; @@ -52,23 +53,6 @@ public class RenderMapping implements Serializable @XmlElement(name = "schema") protected List schemata; - /** - * Default no-arg constructor - * - */ - public RenderMapping() { - super(); - } - - /** - * Fully-initialising value constructor - * - */ - public RenderMapping(final String defaultSchema, final List schemata) { - this.defaultSchema = defaultSchema; - this.schemata = schemata; - } - /** * Gets the value of the defaultSchema property. * diff --git a/jOOQ/src/main/java/org/jooq/conf/Rendering.java b/jOOQ/src/main/java/org/jooq/conf/Rendering.java index 0c42fa27ac..e0421301fc 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Rendering.java +++ b/jOOQ/src/main/java/org/jooq/conf/Rendering.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @@ -37,28 +37,13 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "Rendering", propOrder = { }) -public class Rendering implements Serializable +public class Rendering + implements Serializable { private final static long serialVersionUID = 205L; protected RenderMapping renderMapping; - /** - * Default no-arg constructor - * - */ - public Rendering() { - super(); - } - - /** - * Fully-initialising value constructor - * - */ - public Rendering(final RenderMapping renderMapping) { - this.renderMapping = renderMapping; - } - /** * Gets the value of the renderMapping property. * diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index f4759f79ba..998901673c 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @@ -38,30 +38,14 @@ import javax.xml.bind.annotation.XmlType; @XmlType(name = "Settings", propOrder = { }) -public class Settings implements Serializable +public class Settings + implements Serializable { private final static long serialVersionUID = 205L; protected Rendering rendering; protected Execution execution; - /** - * Default no-arg constructor - * - */ - public Settings() { - super(); - } - - /** - * Fully-initialising value constructor - * - */ - public Settings(final Rendering rendering, final Execution execution) { - this.rendering = rendering; - this.execution = execution; - } - /** * Gets the value of the rendering property. * diff --git a/jOOQ/src/main/java/org/jooq/conf/StatementType.java b/jOOQ/src/main/java/org/jooq/conf/StatementType.java index 165edc1bcd..7f21753d70 100644 --- a/jOOQ/src/main/java/org/jooq/conf/StatementType.java +++ b/jOOQ/src/main/java/org/jooq/conf/StatementType.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // diff --git a/jOOQ/src/main/java/org/jooq/conf/package-info.java b/jOOQ/src/main/java/org/jooq/conf/package-info.java index aa37c6d23a..bc953befad 100644 --- a/jOOQ/src/main/java/org/jooq/conf/package-info.java +++ b/jOOQ/src/main/java/org/jooq/conf/package-info.java @@ -2,7 +2,7 @@ // This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.0.5-b02-fcs // See http://java.sun.com/xml/jaxb // Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2012.02.15 at 10:19:56 PM MEZ +// Generated on: 2012.02.16 at 09:35:19 PM MEZ // @javax.xml.bind.annotation.XmlSchema(namespace = "http://www.jooq.org/xsd/jooq-runtime-2.0.5.xsd") diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java index cefc4354c6..eb027bad94 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQuery.java @@ -36,6 +36,9 @@ package org.jooq.impl; +import static org.jooq.conf.StatementType.PREPARED_STATEMENT; +import static org.jooq.impl.Util.getStatementType; + import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -124,19 +127,28 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query { String sql = null; int result = 0; try { - sql = create(configuration).render(this); + sql = getSQL(); watch.splitTrace("SQL rendered"); + // [#1145] Depending on the configuration, a prepared statement + // or an "ad-hoc" statement is used + boolean usePreparedStatement = + getStatementType(getConfiguration().getSettings()) == PREPARED_STATEMENT; + if (log.isDebugEnabled()) - log.debug("Executing query", create(configuration).renderInlined(this)); - if (log.isTraceEnabled()) + log.debug("Executing query", getSQL(true)); + if (log.isTraceEnabled() && usePreparedStatement) log.trace("Preparing statement", sql); statement = prepare(configuration, sql); - watch.splitTrace("Statement prepared"); - create(configuration).bind(this, statement); - watch.splitTrace("Variables bound"); + // [#1145] Bind variables only for true prepared statements + if (usePreparedStatement) { + watch.splitTrace("Statement prepared"); + + create(configuration).bind(this, statement); + watch.splitTrace("Variables bound"); + } result = execute(configuration, statement); watch.splitTrace("Statement executed"); @@ -184,8 +196,8 @@ abstract class AbstractQuery extends AbstractQueryPart implements Query { } /** - * Default implementation for query execution. Subclasses may override this - * method. + * Default implementation for query execution using a prepared statement. + * Subclasses may override this method. * * @param configuration The configuration that is used for this query's * execution. diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractQueryPart.java b/jOOQ/src/main/java/org/jooq/impl/AbstractQueryPart.java index 8841bed7f1..58cee0eca8 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractQueryPart.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractQueryPart.java @@ -36,6 +36,8 @@ package org.jooq.impl; +import static org.jooq.conf.StatementType.STATEMENT; + import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; @@ -53,7 +55,6 @@ import org.jooq.QueryPart; import org.jooq.QueryPartInternal; import org.jooq.SQLDialect; import org.jooq.Store; -import org.jooq.conf.StatementType; import org.jooq.exception.DataAccessException; import org.jooq.exception.SQLDialectNotSupportedException; @@ -114,7 +115,7 @@ abstract class AbstractQueryPart implements QueryPartInternal, AttachableInterna */ @Override public final String getSQL() { - if (Util.getStatementType(create().getSettings()) == StatementType.STATEMENT) { + if (Util.getStatementType(create().getSettings()) == STATEMENT) { return getSQL(true); } else { diff --git a/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java b/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java new file mode 100644 index 0000000000..509d2e0fd8 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/ConnectionProxy.java @@ -0,0 +1,363 @@ +/** + * Copyright (c) 2009-2012, 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.impl; + +import static org.jooq.conf.StatementType.PREPARED_STATEMENT; + +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.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Savepoint; +import java.sql.Statement; +import java.sql.Struct; +import java.util.Map; +import java.util.Properties; + +import org.jooq.conf.Settings; +import org.jooq.conf.StatementType; + +/** + * A proxy for a JDBC {@link Connection} that handles creation of prepared + * statements according to the settings' {@link StatementType} + * + * @author Lukas Eder + */ +class ConnectionProxy implements Connection { + + private final Connection delegate; + private final Settings settings; + + ConnectionProxy(Connection delegate, Settings settings) { + this.delegate = delegate; + this.settings = settings; + } + + // ------------------------------------------------------------------------ + // XXX Creation of PreparedStatements + // ------------------------------------------------------------------------ + + @Override + public final PreparedStatement prepareStatement(String sql) throws SQLException { + if (Util.getStatementType(settings) == PREPARED_STATEMENT) { + return delegate.prepareStatement(sql); + } + else { + return new PreparedStatementProxy(delegate, sql); + } + } + + @Override + public final PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) + throws SQLException { + if (Util.getStatementType(settings) == PREPARED_STATEMENT) { + return delegate.prepareStatement(sql, resultSetType, resultSetConcurrency); + } + else { + return new PreparedStatementProxy(delegate, sql, resultSetType, resultSetConcurrency); + } + } + + @Override + public final PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + if (Util.getStatementType(settings) == PREPARED_STATEMENT) { + return delegate.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + else { + return new PreparedStatementProxy(delegate, sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + } + + @Override + public final PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + if (Util.getStatementType(settings) == PREPARED_STATEMENT) { + return delegate.prepareStatement(sql, autoGeneratedKeys); + } + else { + return new PreparedStatementProxy(delegate, sql, autoGeneratedKeys); + } + } + + @Override + public final PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + if (Util.getStatementType(settings) == PREPARED_STATEMENT) { + return delegate.prepareStatement(sql, columnIndexes); + } + else { + return new PreparedStatementProxy(delegate, sql, columnIndexes); + } + } + + @Override + public final PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + if (Util.getStatementType(settings) == PREPARED_STATEMENT) { + return delegate.prepareStatement(sql, columnNames); + } + else { + return new PreparedStatementProxy(delegate, sql, columnNames); + } + } + + // ------------------------------------------------------------------------ + // XXX Other methods + // ------------------------------------------------------------------------ + + @Override + public final T unwrap(Class iface) throws SQLException { + return delegate.unwrap(iface); + } + + @Override + public final boolean isWrapperFor(Class iface) throws SQLException { + return delegate.isWrapperFor(iface); + } + + @Override + public final Statement createStatement() throws SQLException { + return delegate.createStatement(); + } + + @Override + public final CallableStatement prepareCall(String sql) throws SQLException { + return delegate.prepareCall(sql); + } + + @Override + public final String nativeSQL(String sql) throws SQLException { + return delegate.nativeSQL(sql); + } + + @Override + public final void setAutoCommit(boolean autoCommit) throws SQLException { + delegate.setAutoCommit(autoCommit); + } + + @Override + public final boolean getAutoCommit() throws SQLException { + return delegate.getAutoCommit(); + } + + @Override + public final void commit() throws SQLException { + delegate.commit(); + } + + @Override + public final void rollback() throws SQLException { + delegate.rollback(); + } + + @Override + public final void close() throws SQLException { + delegate.close(); + } + + @Override + public final boolean isClosed() throws SQLException { + return delegate.isClosed(); + } + + @Override + public final DatabaseMetaData getMetaData() throws SQLException { + return delegate.getMetaData(); + } + + @Override + public final void setReadOnly(boolean readOnly) throws SQLException { + delegate.setReadOnly(readOnly); + } + + @Override + public final boolean isReadOnly() throws SQLException { + return delegate.isReadOnly(); + } + + @Override + public final void setCatalog(String catalog) throws SQLException { + delegate.setCatalog(catalog); + } + + @Override + public final String getCatalog() throws SQLException { + return delegate.getCatalog(); + } + + @Override + public final void setTransactionIsolation(int level) throws SQLException { + delegate.setTransactionIsolation(level); + } + + @Override + public final int getTransactionIsolation() throws SQLException { + return delegate.getTransactionIsolation(); + } + + @Override + public final SQLWarning getWarnings() throws SQLException { + return delegate.getWarnings(); + } + + @Override + public final void clearWarnings() throws SQLException { + delegate.clearWarnings(); + } + + @Override + public final Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + return delegate.createStatement(resultSetType, resultSetConcurrency); + } + + @Override + public final CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return delegate.prepareCall(sql, resultSetType, resultSetConcurrency); + } + + @Override + public final Map> getTypeMap() throws SQLException { + return delegate.getTypeMap(); + } + + @Override + public final void setTypeMap(Map> map) throws SQLException { + delegate.setTypeMap(map); + } + + @Override + public final void setHoldability(int holdability) throws SQLException { + delegate.setHoldability(holdability); + } + + @Override + public final int getHoldability() throws SQLException { + return delegate.getHoldability(); + } + + @Override + public final Savepoint setSavepoint() throws SQLException { + return delegate.setSavepoint(); + } + + @Override + public final Savepoint setSavepoint(String name) throws SQLException { + return delegate.setSavepoint(name); + } + + @Override + public final void rollback(Savepoint savepoint) throws SQLException { + delegate.rollback(savepoint); + } + + @Override + public final void releaseSavepoint(Savepoint savepoint) throws SQLException { + delegate.releaseSavepoint(savepoint); + } + + @Override + public final Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) + throws SQLException { + return delegate.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public final CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, + int resultSetHoldability) throws SQLException { + return delegate.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability); + } + + @Override + public final Clob createClob() throws SQLException { + return delegate.createClob(); + } + + @Override + public final Blob createBlob() throws SQLException { + return delegate.createBlob(); + } + + @Override + public final NClob createNClob() throws SQLException { + return delegate.createNClob(); + } + + @Override + public final SQLXML createSQLXML() throws SQLException { + return delegate.createSQLXML(); + } + + @Override + public final boolean isValid(int timeout) throws SQLException { + return delegate.isValid(timeout); + } + + @Override + public final void setClientInfo(String name, String value) throws SQLClientInfoException { + delegate.setClientInfo(name, value); + } + + @Override + public final void setClientInfo(Properties properties) throws SQLClientInfoException { + delegate.setClientInfo(properties); + } + + @Override + public final String getClientInfo(String name) throws SQLException { + return delegate.getClientInfo(name); + } + + @Override + public final Properties getClientInfo() throws SQLException { + return delegate.getClientInfo(); + } + + @Override + public final Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return delegate.createArrayOf(typeName, elements); + } + + @Override + public final Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return delegate.createStruct(typeName, attributes); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/Factory.java b/jOOQ/src/main/java/org/jooq/impl/Factory.java index 8bfe3e238e..f5bb3ac486 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Factory.java +++ b/jOOQ/src/main/java/org/jooq/impl/Factory.java @@ -241,7 +241,7 @@ public class Factory implements FactoryOperations { */ @Override public final Connection getConnection() { - return connection; + return new ConnectionProxy(connection, settings); } /** diff --git a/jOOQ/src/main/java/org/jooq/impl/PreparedStatementProxy.java b/jOOQ/src/main/java/org/jooq/impl/PreparedStatementProxy.java new file mode 100644 index 0000000000..ae2c8e2d4f --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/PreparedStatementProxy.java @@ -0,0 +1,697 @@ +/** + * Copyright (c) 2009-2012, 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.impl; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.NClob; +import java.sql.ParameterMetaData; +import java.sql.PreparedStatement; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLWarning; +import java.sql.SQLXML; +import java.sql.Statement; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; + +/** + * A proxy for a JDBC {@link PreparedStatement} that simulates the API of a + * prepared statement, when in fact executing an ad-hoc {@link Statement} + * + * @author Lukas Eder + */ +class PreparedStatementProxy implements PreparedStatement { + + private final Connection connection; + private final Statement delegate; + private final MethodType methodType; + private final String sql; + private int autoGeneratedKeys; + private int[] columnIndexes; + private String[] columnNames; + + // ------------------------------------------------------------------------ + // XXX: Creation of PreparedStatements + // ------------------------------------------------------------------------ + + private PreparedStatementProxy(Connection connection, String sql, MethodType type, Statement statement) { + this.connection = connection; + this.methodType = type; + this.sql = sql; + this.delegate = statement; + } + + private PreparedStatementProxy(Connection connection, String sql, MethodType type) throws SQLException { + this(connection, sql, type, connection.createStatement()); + } + + PreparedStatementProxy(Connection connection, String sql) throws SQLException { + this(connection, sql, MethodType.SQL); + } + + PreparedStatementProxy(Connection connection, String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + this(connection, sql, MethodType.SQL_RST_RSC, connection.createStatement(resultSetType, resultSetConcurrency)); + } + + PreparedStatementProxy(Connection connection, String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + this(connection, sql, MethodType.SQL_RST_RSC_RSH, connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability)); + } + + PreparedStatementProxy(Connection connection, String sql, int autoGeneratedKeys) throws SQLException { + this(connection, sql, MethodType.SQL_AGK); + + this.autoGeneratedKeys = autoGeneratedKeys; + } + + PreparedStatementProxy(Connection connection, String sql, int[] columnIndexes) throws SQLException { + this(connection, sql, MethodType.SQL_CI); + + this.columnIndexes = columnIndexes; + } + + PreparedStatementProxy(Connection connection, String sql, String[] columnNames) throws SQLException { + this(connection, sql, MethodType.SQL_CN); + + this.columnNames = columnNames; + } + + // ------------------------------------------------------------------------ + // XXX: Utilities + // ------------------------------------------------------------------------ + + /** + * A descriptor for the various methods that can create a prespared + * statement + */ + private static enum MethodType { + + /** + * Corresponds to {@link Connection#prepareStatement(String)} + */ + SQL, + + /** + * Corresponds to {@link Connection#prepareStatement(String, int, int) */ + SQL_RST_RSC, + + /** + * Corresponds to + * {@link Connection#prepareStatement(String, int, int, int) + */ + SQL_RST_RSC_RSH, + + /** + * Corresponds to + * {@link Connection#prepareStatement(String, int) + */ + SQL_AGK, + + /** + * Corresponds to + * {@link Connection#prepareStatement(String, int[]) + */ + SQL_CI, + + /** + * Corresponds to + * {@link Connection#prepareStatement(String, String[]) + */ + SQL_CN + } + + // ------------------------------------------------------------------------ + // XXX: Irrelevant methods from java.sql.Statement + // ------------------------------------------------------------------------ + + @Override + public final void close() throws SQLException { + delegate.close(); + } + + @Override + public final boolean isClosed() throws SQLException { + return delegate.isClosed(); + } + + @Override + public final void cancel() throws SQLException { + delegate.cancel(); + } + + @Override + public final int getMaxFieldSize() throws SQLException { + return delegate.getMaxFieldSize(); + } + + @Override + public final void setMaxFieldSize(int max) throws SQLException { + delegate.setMaxFieldSize(max); + } + + @Override + public final int getMaxRows() throws SQLException { + return delegate.getMaxRows(); + } + + @Override + public final void setMaxRows(int max) throws SQLException { + delegate.setMaxRows(max); + } + + @Override + public final void setEscapeProcessing(boolean enable) throws SQLException { + delegate.setEscapeProcessing(enable); + } + + @Override + public final int getQueryTimeout() throws SQLException { + return delegate.getQueryTimeout(); + } + + @Override + public final void setQueryTimeout(int seconds) throws SQLException { + delegate.setQueryTimeout(seconds); + } + + @Override + public final SQLWarning getWarnings() throws SQLException { + return delegate.getWarnings(); + } + + @Override + public final void clearWarnings() throws SQLException { + delegate.clearWarnings(); + } + + @Override + public final void setCursorName(String name) throws SQLException { + delegate.setCursorName(name); + } + + @Override + public final ResultSet getResultSet() throws SQLException { + return delegate.getResultSet(); + } + + @Override + public final int getUpdateCount() throws SQLException { + return delegate.getUpdateCount(); + } + + @Override + public final boolean getMoreResults() throws SQLException { + return delegate.getMoreResults(); + } + + @Override + public final void setPoolable(boolean poolable) throws SQLException { + delegate.setPoolable(poolable); + } + + @Override + public final boolean isPoolable() throws SQLException { + return delegate.isPoolable(); + } + + @Override + public final T unwrap(Class iface) throws SQLException { + return delegate.unwrap(iface); + } + + @Override + public final boolean isWrapperFor(Class iface) throws SQLException { + return delegate.isWrapperFor(iface); + } + + @Override + public final void setFetchDirection(int direction) throws SQLException { + delegate.setFetchDirection(direction); + } + + @Override + public final int getFetchDirection() throws SQLException { + return delegate.getFetchDirection(); + } + + @Override + public final void setFetchSize(int rows) throws SQLException { + delegate.setFetchSize(rows); + } + + @Override + public final int getFetchSize() throws SQLException { + return delegate.getFetchSize(); + } + + @Override + public final int getResultSetConcurrency() throws SQLException { + return delegate.getResultSetConcurrency(); + } + + @Override + public final int getResultSetType() throws SQLException { + return delegate.getResultSetType(); + } + + @Override + public final int getResultSetHoldability() throws SQLException { + return delegate.getResultSetHoldability(); + } + + @Override + public final Connection getConnection() throws SQLException { + return connection; + } + + @Override + public final boolean getMoreResults(int current) throws SQLException { + return delegate.getMoreResults(); + } + + @Override + public final ResultSet getGeneratedKeys() throws SQLException { + return delegate.getGeneratedKeys(); + } + + // ------------------------------------------------------------------------ + // XXX: Execute methods from java.sql.PreparedStatement + // ------------------------------------------------------------------------ + + @Override + public final ResultSet executeQuery() throws SQLException { + return delegate.executeQuery(sql); + } + + @Override + public final int executeUpdate() throws SQLException { + switch (methodType) { + case SQL_AGK: + return delegate.executeUpdate(sql, autoGeneratedKeys); + case SQL_CI: + return delegate.executeUpdate(sql, columnIndexes); + case SQL_CN: + return delegate.executeUpdate(sql, columnNames); + + case SQL: + case SQL_RST_RSC: + case SQL_RST_RSC_RSH: + default: + return delegate.executeUpdate(sql); + } + } + + @Override + public final boolean execute() throws SQLException { + switch (methodType) { + case SQL_AGK: + return delegate.execute(sql, autoGeneratedKeys); + case SQL_CI: + return delegate.execute(sql, columnIndexes); + case SQL_CN: + return delegate.execute(sql, columnNames); + + case SQL: + case SQL_RST_RSC: + case SQL_RST_RSC_RSH: + default: + return delegate.execute(sql); + } + } + + // ------------------------------------------------------------------------ + // XXX: Unsupported batch methods + // ------------------------------------------------------------------------ + + @Override + public final void addBatch() throws SQLException { + throw new UnsupportedOperationException("Cannot batch execute statements on PreparedStatementProxy"); + } + + @Override + public final void clearBatch() throws SQLException { + throw new UnsupportedOperationException("Cannot batch execute statements on PreparedStatementProxy"); + } + + @Override + public final int[] executeBatch() throws SQLException { + throw new UnsupportedOperationException("Cannot batch execute statements on PreparedStatementProxy"); + } + + @Override + public final void addBatch(String query) throws SQLException { + throw new UnsupportedOperationException("Cannot batch execute statements on PreparedStatementProxy"); + } + + // ------------------------------------------------------------------------ + // XXX: Unsupported execute methods from java.sql.Statement + // ------------------------------------------------------------------------ + + @Override + public final boolean execute(String query) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final ResultSet executeQuery(String query) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final int executeUpdate(String query) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final int executeUpdate(String query, int pAutoGeneratedKeys) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final int executeUpdate(String query, int[] pColumnIndexes) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final int executeUpdate(String query, String[] pColumnNames) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final boolean execute(String query, int pAutoGeneratedKeys) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final boolean execute(String query, int[] pColumnIndexes) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + @Override + public final boolean execute(String query, String[] pColumnNames) throws SQLException { + throw new UnsupportedOperationException("Cannot use java.sql.Statement.executeXXX() methods on PreparedStatementProxy"); + } + + // ------------------------------------------------------------------------ + // XXX: Unsupported bind variable methods from java.sql.PreparedStatement + // ------------------------------------------------------------------------ + + @Override + public final ResultSetMetaData getMetaData() throws SQLException { + throw new UnsupportedOperationException("Cannot fetch ResultSetMetaData early on PreparedStatementProxy"); + } + + @Override + public final void clearParameters() throws SQLException { + throw new UnsupportedOperationException("Cannot operate on bind values on a PreparedStatementProxy"); + } + + @Override + public final ParameterMetaData getParameterMetaData() throws SQLException { + throw new UnsupportedOperationException("Cannot operate on bind values on a PreparedStatementProxy"); + } + + @Override + public final void setNull(int parameterIndex, int sqlType) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBoolean(int parameterIndex, boolean x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setByte(int parameterIndex, byte x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setShort(int parameterIndex, short x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setInt(int parameterIndex, int x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setLong(int parameterIndex, long x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setFloat(int parameterIndex, float x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setDouble(int parameterIndex, double x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setString(int parameterIndex, String x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBytes(int parameterIndex, byte[] x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setDate(int parameterIndex, Date x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setTime(int parameterIndex, Time x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setTimestamp(int parameterIndex, Timestamp x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setObject(int parameterIndex, Object x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setRef(int parameterIndex, Ref x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBlob(int parameterIndex, Blob x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setClob(int parameterIndex, Clob x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setArray(int parameterIndex, Array x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setURL(int parameterIndex, URL x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setRowId(int parameterIndex, RowId x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNString(int parameterIndex, String value) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNClob(int parameterIndex, NClob value) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNClob(int parameterIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setAsciiStream(int parameterIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBinaryStream(int parameterIndex, InputStream x) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setCharacterStream(int parameterIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNCharacterStream(int parameterIndex, Reader value) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setClob(int parameterIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setBlob(int parameterIndex, InputStream inputStream) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } + + @Override + public final void setNClob(int parameterIndex, Reader reader) throws SQLException { + throw new UnsupportedOperationException("Cannot set a bind value on a PreparedStatementProxy"); + } +}