[jOOQ/jOOQ#12528] Add ExecuteScope, a Scope that knows about an ExecuteContext
This includes: - [jOOQ/jOOQ#12527] DefaultExecuteContext.LOCAL_SCOPE is reset to null when nesting lazy executions
This commit is contained in:
parent
a9d8e9e67d
commit
857edd0ecb
@ -45,7 +45,7 @@ import java.sql.ResultSet;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface BindingGetResultSetContext<U> extends Scope {
|
||||
public interface BindingGetResultSetContext<U> extends ExecuteScope {
|
||||
|
||||
/**
|
||||
* The {@link ResultSet} from which a value is retrieved.
|
||||
|
||||
@ -45,7 +45,7 @@ import java.sql.SQLInput;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface BindingGetSQLInputContext<U> extends Scope {
|
||||
public interface BindingGetSQLInputContext<U> extends ExecuteScope {
|
||||
|
||||
/**
|
||||
* The {@link SQLInput} from which a value is retrieved.
|
||||
|
||||
@ -45,7 +45,7 @@ import java.sql.CallableStatement;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface BindingGetStatementContext<U> extends Scope {
|
||||
public interface BindingGetStatementContext<U> extends ExecuteScope {
|
||||
|
||||
/**
|
||||
* The {@link CallableStatement} from which a value is retrieved.
|
||||
|
||||
@ -45,7 +45,7 @@ import java.sql.CallableStatement;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface BindingRegisterContext<U> extends Scope {
|
||||
public interface BindingRegisterContext<U> extends ExecuteScope {
|
||||
|
||||
/**
|
||||
* The {@link CallableStatement} on which a bind variable should be
|
||||
|
||||
@ -45,7 +45,7 @@ import java.sql.SQLOutput;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface BindingSetSQLOutputContext<U> extends ResourceManagingScope {
|
||||
public interface BindingSetSQLOutputContext<U> extends ResourceManagingScope, ExecuteScope {
|
||||
|
||||
/**
|
||||
* The {@link SQLOutput} to which a bind variable should be bound.
|
||||
|
||||
@ -45,7 +45,7 @@ import java.sql.PreparedStatement;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface BindingSetStatementContext<U> extends ResourceManagingScope {
|
||||
public interface BindingSetStatementContext<U> extends ResourceManagingScope, ExecuteScope {
|
||||
|
||||
/**
|
||||
* The {@link PreparedStatement} to which a bind variable should be bound.
|
||||
|
||||
55
jOOQ/src/main/java/org/jooq/ExecuteScope.java
Normal file
55
jOOQ/src/main/java/org/jooq/ExecuteScope.java
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A {@link Scope} that knows its {@link ExecuteContext}.
|
||||
*/
|
||||
public interface ExecuteScope extends Scope {
|
||||
|
||||
/**
|
||||
* The {@link ExecuteContext} that created this scope.
|
||||
*
|
||||
* @return The execute context. Can be <code>null</code> e.g. when running
|
||||
* in an R2DBC context, see [#11717].
|
||||
*/
|
||||
@Nullable
|
||||
ExecuteContext executeContext();
|
||||
}
|
||||
62
jOOQ/src/main/java/org/jooq/impl/AbstractExecuteScope.java
Normal file
62
jOOQ/src/main/java/org/jooq/impl/AbstractExecuteScope.java
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.ExecuteScope;
|
||||
|
||||
/**
|
||||
* Base class for {@link ExecuteScope}.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
abstract class AbstractExecuteScope extends AbstractScope implements ExecuteScope {
|
||||
|
||||
final ExecuteContext ctx;
|
||||
|
||||
AbstractExecuteScope(ExecuteContext ctx) {
|
||||
super(ctx.configuration(), ctx.data());
|
||||
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExecuteContext executeContext() {
|
||||
return ctx;
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static org.jooq.impl.DefaultExecuteContext.localScope;
|
||||
import static org.jooq.impl.DefaultExecuteContext.localExecuteContext;
|
||||
import static org.jooq.impl.Tools.fieldsArray;
|
||||
import static org.jooq.impl.Tools.getMappedUDTName;
|
||||
import static org.jooq.impl.Tools.row0;
|
||||
@ -47,6 +47,7 @@ import java.sql.SQLInput;
|
||||
import java.sql.SQLOutput;
|
||||
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.RecordQualifier;
|
||||
@ -112,18 +113,18 @@ abstract class AbstractQualifiedRecord<R extends QualifiedRecord<R>> extends Abs
|
||||
|
||||
// [#1693] This needs to return the fully qualified SQL type name, in
|
||||
// case the connected user is not the owner of the UDT
|
||||
return getMappedUDTName(localScope(), this);
|
||||
return getMappedUDTName(localExecuteContext(), this);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public final void readSQL(SQLInput stream, String typeName) throws SQLException {
|
||||
Scope scope = localScope();
|
||||
ExecuteContext ctx = localExecuteContext();
|
||||
Field<?>[] f = getQualifier().fields();
|
||||
|
||||
for (int i = 0; i < f.length; i++) {
|
||||
Field field = f[i];
|
||||
DefaultBindingGetSQLInputContext out = new DefaultBindingGetSQLInputContext(scope.configuration(), scope.data(), stream);
|
||||
DefaultBindingGetSQLInputContext out = new DefaultBindingGetSQLInputContext(ctx, stream);
|
||||
field.getBinding().get(out);
|
||||
set(i, field, out.value());
|
||||
}
|
||||
@ -132,10 +133,10 @@ abstract class AbstractQualifiedRecord<R extends QualifiedRecord<R>> extends Abs
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Override
|
||||
public final void writeSQL(SQLOutput stream) throws SQLException {
|
||||
Scope scope = localScope();
|
||||
ExecuteContext ctx = localExecuteContext();
|
||||
Field<?>[] f = getQualifier().fields();
|
||||
|
||||
for (int i = 0; i < f.length; i++)
|
||||
f[i].getBinding().set(new DefaultBindingSetSQLOutputContext(scope.configuration(), scope.data(), stream, get(i)));
|
||||
f[i].getBinding().set(new DefaultBindingSetSQLOutputContext(ctx, stream, get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1312,10 +1312,6 @@ implements
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1463,8 +1459,7 @@ implements
|
||||
|
||||
{
|
||||
DefaultBindingGetStatementContext<U> out = new DefaultBindingGetStatementContext<>(
|
||||
ctx.configuration(),
|
||||
ctx.data(),
|
||||
ctx,
|
||||
(CallableStatement) ctx.statement(),
|
||||
resultIndexes.get(parameter)
|
||||
);
|
||||
@ -1476,17 +1471,16 @@ implements
|
||||
|
||||
private final void registerOutParameters(ExecuteContext ctx) throws SQLException {
|
||||
Configuration c = ctx.configuration();
|
||||
Map<Object, Object> data = ctx.data();
|
||||
CallableStatement statement = (CallableStatement) ctx.statement();
|
||||
|
||||
// Register all out / inout parameters according to their position
|
||||
// Note that some RDBMS do not support binding by name very well
|
||||
for (Parameter<?> parameter : getParameters0(ctx.configuration()))
|
||||
if (resultParameter(c, parameter))
|
||||
registerOutParameter(c, data, statement, parameter);
|
||||
registerOutParameter(ctx, statement, parameter);
|
||||
}
|
||||
|
||||
private final <U> void registerOutParameter(Configuration c, Map<Object, Object> data, CallableStatement statement, Parameter<U> parameter) throws SQLException {
|
||||
private final <U> void registerOutParameter(ExecuteContext ctx, CallableStatement statement, Parameter<U> parameter) throws SQLException {
|
||||
|
||||
|
||||
|
||||
@ -1495,7 +1489,7 @@ implements
|
||||
|
||||
|
||||
|
||||
parameter.getBinding().register(new DefaultBindingRegisterContext<>(c, data, statement, resultIndexes.get(parameter)));
|
||||
parameter.getBinding().register(new DefaultBindingRegisterContext<>(ctx, statement, resultIndexes.get(parameter)));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@ -129,7 +129,7 @@ final class CursorImpl<R extends Record> extends AbstractCursor<R> {
|
||||
this.keepStatement = keepStatement;
|
||||
this.keepResultSet = keepResultSet;
|
||||
this.rs = new CursorResultSet();
|
||||
this.rsContext = new DefaultBindingGetResultSetContext<>(ctx.configuration(), ctx.data(), rs, 0);
|
||||
this.rsContext = new DefaultBindingGetResultSetContext<>(ctx, rs, 0);
|
||||
|
||||
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ final class DefaultBindContext extends AbstractBindContext {
|
||||
|
||||
try {
|
||||
((Field<Object>) field).getBinding().set(
|
||||
new DefaultBindingSetStatementContext<>(configuration(), data(), stmt, nextIndex, value)
|
||||
new DefaultBindingSetStatementContext<>(new SimpleExecuteContext(configuration(), data()), stmt, nextIndex, value)
|
||||
);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
||||
@ -88,6 +88,7 @@ import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.REQUIRES_LITERAL
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.infinity;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultDoubleBinding.nan;
|
||||
import static org.jooq.impl.DefaultBinding.DefaultJSONBBinding.EMULATE_AS_BLOB;
|
||||
import static org.jooq.impl.DefaultExecuteContext.localExecuteContext;
|
||||
import static org.jooq.impl.DefaultExecuteContext.localTargetConnection;
|
||||
import static org.jooq.impl.Internal.arrayType;
|
||||
import static org.jooq.impl.Keywords.K_ARRAY;
|
||||
@ -203,6 +204,7 @@ import org.jooq.Converter;
|
||||
import org.jooq.Converters;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.EnumType;
|
||||
import org.jooq.ExecuteScope;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONB;
|
||||
@ -1261,7 +1263,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
* Workarounds for the unimplemented Postgres JDBC driver features
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final <T> T pgGetArray(Scope ctx, ResultSet rs, DataType<T> dataType, int index) throws SQLException {
|
||||
private static final <T> T pgGetArray(ExecuteScope ctx, ResultSet rs, DataType<T> dataType, int index) throws SQLException {
|
||||
|
||||
// Get the JDBC Array and check for null. If null, that's OK
|
||||
Array array = null;
|
||||
@ -1289,7 +1291,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
// Try fetching the array as a JDBC ResultSet
|
||||
try (ResultSet arrayRs = array.getResultSet()) {
|
||||
Binding<T, T> binding = binding((DataType<T>) dataType.getArrayComponentDataType());
|
||||
DefaultBindingGetResultSetContext<T> out = new DefaultBindingGetResultSetContext<>(ctx.configuration(), ctx.data(), arrayRs, 2);
|
||||
DefaultBindingGetResultSetContext<T> out = new DefaultBindingGetResultSetContext<>(ctx.executeContext(), arrayRs, 2);
|
||||
|
||||
while (arrayRs.next()) {
|
||||
binding.get(out);
|
||||
@ -1507,7 +1509,6 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static final class DefaultBigDecimalBinding<U> extends AbstractBinding<BigDecimal, U> {
|
||||
@ -3552,7 +3553,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
if (REQUIRE_RECORD_CAST.contains(ctx.dialect()) && value != null)
|
||||
ctx.statement().setString(ctx.index(), PostgresUtils.toPGString(value));
|
||||
else
|
||||
ctx.statement().setObject(ctx.index(), value);
|
||||
localExecuteContext(ctx.executeContext(), () -> { ctx.statement().setObject(ctx.index(), value); return null; });
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@ -3587,7 +3588,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
return pgNewRecord(dataType.getType(), null, ctx.resultSet().getObject(ctx.index()));
|
||||
|
||||
default:
|
||||
return (Record) ctx.resultSet().getObject(ctx.index(), typeMap(dataType.getType(), ctx));
|
||||
return localExecuteContext(ctx.executeContext(), () -> (Record) ctx.resultSet().getObject(ctx.index(), typeMap(dataType.getType(), ctx)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3601,7 +3602,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
return pgNewRecord(dataType.getType(), null, ctx.statement().getObject(ctx.index()));
|
||||
|
||||
default:
|
||||
return (Record) ctx.statement().getObject(ctx.index(), typeMap(dataType.getType(), ctx));
|
||||
return localExecuteContext(ctx.executeContext(), () -> (Record) ctx.statement().getObject(ctx.index(), typeMap(dataType.getType(), ctx)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -38,26 +38,25 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindingGetResultSetContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.Field;
|
||||
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DefaultBindingGetResultSetContext<U> extends AbstractScope implements BindingGetResultSetContext<U> {
|
||||
class DefaultBindingGetResultSetContext<U> extends AbstractExecuteScope implements BindingGetResultSetContext<U> {
|
||||
|
||||
private final ResultSet resultSet;
|
||||
private int index;
|
||||
private Field<U> field;
|
||||
private U value;
|
||||
|
||||
DefaultBindingGetResultSetContext(Configuration configuration, Map<Object, Object> data, ResultSet resultSet, int index) {
|
||||
super(configuration, data);
|
||||
DefaultBindingGetResultSetContext(ExecuteContext ctx, ResultSet resultSet, int index) {
|
||||
super(ctx);
|
||||
|
||||
this.resultSet = resultSet;
|
||||
this.index = index;
|
||||
@ -99,7 +98,7 @@ class DefaultBindingGetResultSetContext<U> extends AbstractScope implements Bind
|
||||
public final <T> BindingGetResultSetContext<T> convert(final Converter<? super T, ? extends U> converter) {
|
||||
final DefaultBindingGetResultSetContext<U> outer = this;
|
||||
|
||||
return new DefaultBindingGetResultSetContext<T>(configuration, data, resultSet, index) {
|
||||
return new DefaultBindingGetResultSetContext<T>(ctx, resultSet, index) {
|
||||
@Override
|
||||
public void value(T v) {
|
||||
outer.value(converter.from(v));
|
||||
|
||||
@ -38,22 +38,21 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.sql.SQLInput;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindingGetSQLInputContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DefaultBindingGetSQLInputContext<U> extends AbstractScope implements BindingGetSQLInputContext<U> {
|
||||
class DefaultBindingGetSQLInputContext<U> extends AbstractExecuteScope implements BindingGetSQLInputContext<U> {
|
||||
|
||||
private final SQLInput input;
|
||||
private U value;
|
||||
|
||||
DefaultBindingGetSQLInputContext(Configuration configuration, Map<Object, Object> data, SQLInput input) {
|
||||
super(configuration, data);
|
||||
DefaultBindingGetSQLInputContext(ExecuteContext ctx, SQLInput input) {
|
||||
super(ctx);
|
||||
|
||||
this.input = input;
|
||||
}
|
||||
@ -76,7 +75,7 @@ class DefaultBindingGetSQLInputContext<U> extends AbstractScope implements Bindi
|
||||
public final <T> BindingGetSQLInputContext<T> convert(final Converter<? super T, ? extends U> converter) {
|
||||
final DefaultBindingGetSQLInputContext<U> outer = this;
|
||||
|
||||
return new DefaultBindingGetSQLInputContext<T>(configuration, data, input) {
|
||||
return new DefaultBindingGetSQLInputContext<T>(ctx, input) {
|
||||
@Override
|
||||
public void value(T v) {
|
||||
outer.value(converter.from(v));
|
||||
|
||||
@ -38,23 +38,22 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindingGetStatementContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DefaultBindingGetStatementContext<U> extends AbstractScope implements BindingGetStatementContext<U> {
|
||||
class DefaultBindingGetStatementContext<U> extends AbstractExecuteScope implements BindingGetStatementContext<U> {
|
||||
|
||||
private final CallableStatement statement;
|
||||
private final int index;
|
||||
private U value;
|
||||
|
||||
DefaultBindingGetStatementContext(Configuration configuration, Map<Object, Object> data, CallableStatement statement, int index) {
|
||||
super(configuration, data);
|
||||
DefaultBindingGetStatementContext(ExecuteContext ctx, CallableStatement statement, int index) {
|
||||
super(ctx);
|
||||
|
||||
this.statement = statement;
|
||||
this.index = index;
|
||||
@ -83,7 +82,7 @@ class DefaultBindingGetStatementContext<U> extends AbstractScope implements Bind
|
||||
public final <T> BindingGetStatementContext<T> convert(final Converter<? super T, ? extends U> converter) {
|
||||
final DefaultBindingGetStatementContext<U> outer = this;
|
||||
|
||||
return new DefaultBindingGetStatementContext<T>(configuration, data, statement, index) {
|
||||
return new DefaultBindingGetStatementContext<T>(ctx, statement, index) {
|
||||
@Override
|
||||
public void value(T v) {
|
||||
outer.value(converter.from(v));
|
||||
|
||||
@ -38,22 +38,21 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindingRegisterContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DefaultBindingRegisterContext<U> extends AbstractScope implements BindingRegisterContext<U> {
|
||||
class DefaultBindingRegisterContext<U> extends AbstractExecuteScope implements BindingRegisterContext<U> {
|
||||
|
||||
private final CallableStatement statement;
|
||||
private final int index;
|
||||
|
||||
DefaultBindingRegisterContext(Configuration configuration, Map<Object, Object> data, CallableStatement statement, int index) {
|
||||
super(configuration, data);
|
||||
DefaultBindingRegisterContext(ExecuteContext ctx, CallableStatement statement, int index) {
|
||||
super(ctx);
|
||||
|
||||
this.statement = statement;
|
||||
this.index = index;
|
||||
@ -71,7 +70,7 @@ class DefaultBindingRegisterContext<U> extends AbstractScope implements BindingR
|
||||
|
||||
@Override
|
||||
public final <T> BindingRegisterContext<T> convert(Converter<? super T, ? extends U> converter) {
|
||||
return new DefaultBindingRegisterContext<>(configuration, data, statement, index);
|
||||
return new DefaultBindingRegisterContext<>(ctx, statement, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -38,22 +38,21 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.sql.SQLOutput;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindingSetSQLOutputContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DefaultBindingSetSQLOutputContext<U> extends AbstractResourceManagingScope implements BindingSetSQLOutputContext<U> {
|
||||
class DefaultBindingSetSQLOutputContext<U> extends AbstractExecuteScope implements BindingSetSQLOutputContext<U>, ResourceManagingScopeTrait {
|
||||
|
||||
private final SQLOutput output;
|
||||
private final U value;
|
||||
|
||||
DefaultBindingSetSQLOutputContext(Configuration configuration, Map<Object, Object> data, SQLOutput output, U value) {
|
||||
super(configuration, data);
|
||||
DefaultBindingSetSQLOutputContext(ExecuteContext ctx, SQLOutput output, U value) {
|
||||
super(ctx);
|
||||
|
||||
this.output = output;
|
||||
this.value = value;
|
||||
@ -71,7 +70,7 @@ class DefaultBindingSetSQLOutputContext<U> extends AbstractResourceManagingScope
|
||||
|
||||
@Override
|
||||
public final <T> BindingSetSQLOutputContext<T> convert(Converter<? extends T, ? super U> converter) {
|
||||
return new DefaultBindingSetSQLOutputContext<>(configuration, data, output, converter.to(value));
|
||||
return new DefaultBindingSetSQLOutputContext<>(ctx, output, converter.to(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -38,23 +38,22 @@
|
||||
package org.jooq.impl;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.BindingSetStatementContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.ExecuteContext;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class DefaultBindingSetStatementContext<U> extends AbstractResourceManagingScope implements BindingSetStatementContext<U> {
|
||||
class DefaultBindingSetStatementContext<U> extends AbstractExecuteScope implements BindingSetStatementContext<U>, ResourceManagingScopeTrait {
|
||||
|
||||
private final PreparedStatement statement;
|
||||
private final int index;
|
||||
private final U value;
|
||||
|
||||
DefaultBindingSetStatementContext(Configuration configuration, Map<Object, Object> data, PreparedStatement statement, int index, U value) {
|
||||
super(configuration, data);
|
||||
DefaultBindingSetStatementContext(ExecuteContext ctx, PreparedStatement statement, int index, U value) {
|
||||
super(ctx);
|
||||
|
||||
this.statement = statement;
|
||||
this.index = index;
|
||||
@ -78,7 +77,7 @@ class DefaultBindingSetStatementContext<U> extends AbstractResourceManagingScope
|
||||
|
||||
@Override
|
||||
public final <T> BindingSetStatementContext<T> convert(Converter<? extends T, ? super U> converter) {
|
||||
return new DefaultBindingSetStatementContext<>(configuration, data, statement, index, converter.to(value));
|
||||
return new DefaultBindingSetStatementContext<>(ctx, statement, index, converter.to(value));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -169,7 +169,6 @@ class DefaultExecuteContext implements ExecuteContext {
|
||||
RESOURCES.remove();
|
||||
}
|
||||
|
||||
LOCAL_SCOPE.remove();
|
||||
LOCAL_CONNECTION.remove();
|
||||
}
|
||||
|
||||
@ -219,17 +218,39 @@ class DefaultExecuteContext implements ExecuteContext {
|
||||
// XXX: Static utility methods for handling Configuration lifecycle
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final ThreadLocal<Scope> LOCAL_SCOPE = new ThreadLocal<>();
|
||||
private static final ThreadLocal<ExecuteContext> LOCAL_EXECUTE_CONTEXT = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* Get the registered scope.
|
||||
* Get the registered {@link ExecuteContext}.
|
||||
* <p>
|
||||
* It can be safely assumed that such a configuration is available once the
|
||||
* {@link ExecuteContext} has been established, until the statement is
|
||||
* closed.
|
||||
*/
|
||||
static final Scope localScope() {
|
||||
return LOCAL_SCOPE.get();
|
||||
static final ExecuteContext localExecuteContext() {
|
||||
return LOCAL_EXECUTE_CONTEXT.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a runnable with a new {@link #localExecuteContext()}.
|
||||
*/
|
||||
static final <E extends Exception> void localExecuteContext(ExecuteContext ctx, ThrowingRunnable<E> runnable) throws E {
|
||||
localExecuteContext(ctx, () -> { runnable.run(); return null; });
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a supplier with a new {@link #localExecuteContext()}.
|
||||
*/
|
||||
static final <T, E extends Exception> T localExecuteContext(ExecuteContext ctx, ThrowingSupplier<T, E> supplier) throws E {
|
||||
ExecuteContext old = localExecuteContext();
|
||||
|
||||
try {
|
||||
LOCAL_EXECUTE_CONTEXT.set(ctx);
|
||||
return supplier.get();
|
||||
}
|
||||
finally {
|
||||
LOCAL_EXECUTE_CONTEXT.set(old);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
@ -339,7 +360,6 @@ class DefaultExecuteContext implements ExecuteContext {
|
||||
}
|
||||
|
||||
clean();
|
||||
LOCAL_SCOPE.set(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -313,9 +313,8 @@ final class R2DBC {
|
||||
return (R) delegate.operate(record -> {
|
||||
|
||||
// TODO: What data to pass here?
|
||||
DefaultBindingGetResultSetContext<?> ctx = new DefaultBindingGetResultSetContext<>(
|
||||
query.configuration(),
|
||||
query.configuration().data(),
|
||||
DefaultBindingGetResultSetContext<?> ctx = new DefaultBindingGetResultSetContext(
|
||||
new SimpleExecuteContext(query.configuration(), query.configuration().data()),
|
||||
new R2DBCResultSet(query.configuration(), row, meta),
|
||||
0
|
||||
);
|
||||
|
||||
@ -42,60 +42,50 @@ import java.sql.Array;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Clob;
|
||||
import java.sql.SQLXML;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ResourceManagingScope;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
abstract class AbstractResourceManagingScope extends AbstractScope implements ResourceManagingScope {
|
||||
|
||||
AbstractResourceManagingScope(Configuration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
AbstractResourceManagingScope(Configuration configuration, Map<Object, Object> data) {
|
||||
super(configuration, data);
|
||||
}
|
||||
interface ResourceManagingScopeTrait extends ResourceManagingScope {
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX ResourceManagingScope API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final Array autoFree(Array array) {
|
||||
default Array autoFree(Array array) {
|
||||
DefaultExecuteContext.register(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Blob autoFree(Blob blob) {
|
||||
default Blob autoFree(Blob blob) {
|
||||
DefaultExecuteContext.register(blob);
|
||||
return blob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clob autoFree(Clob clob) {
|
||||
default Clob autoFree(Clob clob) {
|
||||
DefaultExecuteContext.register(clob);
|
||||
return clob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SQLXML autoFree(SQLXML xml) {
|
||||
default SQLXML autoFree(SQLXML xml) {
|
||||
DefaultExecuteContext.register(xml);
|
||||
return xml;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <R extends Closeable> R autoClose(R closeable) {
|
||||
default <R extends Closeable> R autoClose(R closeable) {
|
||||
DefaultExecuteContext.register(closeable);
|
||||
return closeable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final <R extends AutoCloseable> R autoClose(R closeable) {
|
||||
default <R extends AutoCloseable> R autoClose(R closeable) {
|
||||
DefaultExecuteContext.register(closeable);
|
||||
return closeable;
|
||||
}
|
||||
208
jOOQ/src/main/java/org/jooq/impl/SimpleExecuteContext.java
Normal file
208
jOOQ/src/main/java/org/jooq/impl/SimpleExecuteContext.java
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.ConnectionProvider;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.ExecuteContext;
|
||||
import org.jooq.ExecuteType;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Routine;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.conf.Settings;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A simple implementation of {@link ExecuteContext} containing
|
||||
* {@link #configuration()} and {@link #data()} where no actual context is
|
||||
* available.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class SimpleExecuteContext extends AbstractScope implements ExecuteContext {
|
||||
|
||||
SimpleExecuteContext(Configuration configuration, Map<Object, Object> data) {
|
||||
super(configuration, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Connection connection() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ExecuteType type() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query query() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Query[] batchQueries() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Routine<?> routine() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String sql() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void sql(String sql) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String[] batchSQL() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void connectionProvider(ConnectionProvider connectionProvider) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final PreparedStatement statement() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void statement(PreparedStatement statement) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int statementExecutionCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ResultSet resultSet() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void resultSet(ResultSet resultSet) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Record record() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void record(Record record) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int rows() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void rows(int rows) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int [] batchRows() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Result<?> result() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void result(Result<?> result) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RuntimeException exception() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void exception(RuntimeException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SQLException sqlException() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void sqlException(SQLException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final SQLWarning sqlWarning() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void sqlWarning(SQLWarning e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String[] serverOutput() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void serverOutput(String[] output) {
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user