[jOOQ/jOOQ#10438] Support lazy DataType lookups in DSL.val() and
DSL.inline() This includes [jOOQ/jOOQ#9492] Deprecate static data type registry lookups for user defined data types
This commit is contained in:
parent
84e8acc750
commit
af2f5bc935
@ -78,6 +78,10 @@ final class ConvertedDataType<T, U> extends AbstractDataType<U> {
|
||||
|
||||
this.delegate = delegate;
|
||||
this.binding = binding;
|
||||
|
||||
// [#9492] For backwards compatibility reasons, a legacy type registers
|
||||
// itself in the static type registry
|
||||
new LegacyConvertedDataType<>(delegate, binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -270,4 +274,5 @@ final class ConvertedDataType<T, U> extends AbstractDataType<U> {
|
||||
delegate.get(ctx.convert(suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23791,7 +23791,7 @@ public class DSL {
|
||||
@Support
|
||||
public static <T> Param<T> val(T value) {
|
||||
Class type = value == null ? Object.class : value.getClass();
|
||||
return val(value, DefaultDataType.getDataType(DEFAULT, type, new DataTypeProxy((AbstractDataType) SQLDataType.OTHER)));
|
||||
return val(value, getDataType0(type));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25925,7 +25925,7 @@ public class DSL {
|
||||
protected static <T> Field<T> nullSafe(Field<T> field, DataType<?> type) {
|
||||
return field == null
|
||||
? (Field<T>) val((T) null, type)
|
||||
: field instanceof Val && field.getDataType() instanceof DataTypeProxy
|
||||
: field instanceof Val
|
||||
? (Field<T>) ((Val<T>) field).convertTo(type)
|
||||
: field;
|
||||
}
|
||||
@ -26102,6 +26102,29 @@ public class DSL {
|
||||
return DefaultDataType.getDataType(SQLDialect.DEFAULT, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* [#9492] [#10438] Get a static data type for a class.
|
||||
* <p>
|
||||
* This will:
|
||||
* <ul>
|
||||
* <li>Get a built-in data type, if available</li>
|
||||
* <li>Get a DataTypeProxy wrapped LegacyConvertedDataType, if available
|
||||
* (#9492)</li>
|
||||
* <li>Get a DataTypeProxy, otherwise, for lazy data type lookups
|
||||
* (#10438)</li>
|
||||
* </ul>
|
||||
*/
|
||||
static <T> DataType<T> getDataType0(Class<T> type) {
|
||||
DataType t = DefaultDataType.getDataType(DEFAULT, type, (DataType) SQLDataType.OTHER);
|
||||
|
||||
if (t instanceof LegacyConvertedDataType)
|
||||
return new DataTypeProxy((AbstractDataType) t);
|
||||
else if (t != SQLDataType.OTHER)
|
||||
return t;
|
||||
else
|
||||
return DefaultDataType.getDataType(DEFAULT, type, new DataTypeProxy((AbstractDataType) SQLDataType.OTHER));
|
||||
}
|
||||
|
||||
private static final DSLContext dsl() {
|
||||
return using(new DefaultConfiguration());
|
||||
}
|
||||
|
||||
185
jOOQ/src/main/java/org/jooq/impl/LegacyConvertedDataType.java
Normal file
185
jOOQ/src/main/java/org/jooq/impl/LegacyConvertedDataType.java
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* 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.SQLException;
|
||||
|
||||
import org.jooq.Binding;
|
||||
import org.jooq.BindingGetResultSetContext;
|
||||
import org.jooq.BindingGetSQLInputContext;
|
||||
import org.jooq.BindingGetStatementContext;
|
||||
import org.jooq.BindingRegisterContext;
|
||||
import org.jooq.BindingSQLContext;
|
||||
import org.jooq.BindingSetSQLOutputContext;
|
||||
import org.jooq.BindingSetStatementContext;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Converter;
|
||||
import org.jooq.Converters;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
* @deprecated - 3.14.0 - [#9492] [#10312] - A compatibility implementation for
|
||||
* converted data types, which registers itself in the static type
|
||||
* registry for legacy reasons.
|
||||
*/
|
||||
@Deprecated
|
||||
final class LegacyConvertedDataType<T, U> extends DefaultDataType<U> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -2321926692580974126L;
|
||||
|
||||
private final DataType<T> delegate;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
LegacyConvertedDataType(AbstractDataType<T> delegate, Binding<? super T, U> binding) {
|
||||
super(
|
||||
null,
|
||||
binding.converter().toType(),
|
||||
binding,
|
||||
delegate.getQualifiedName(),
|
||||
delegate.getTypeName(),
|
||||
delegate.getCastTypeName(),
|
||||
delegate.precisionDefined() ? delegate.precision() : null,
|
||||
delegate.scaleDefined() ? delegate.scale() : null,
|
||||
delegate.lengthDefined() ? delegate.length() : null,
|
||||
delegate.nullability(),
|
||||
(Field<U>) delegate.defaultValue()
|
||||
);
|
||||
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSQLType() {
|
||||
return delegate.getSQLType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeName(Configuration configuration) {
|
||||
return delegate.getTypeName(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCastTypeName(Configuration configuration) {
|
||||
return delegate.getCastTypeName(configuration);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public U convert(Object object) {
|
||||
if (getConverter().toType().isInstance(object))
|
||||
return (U) object;
|
||||
|
||||
// [#3200] Try to convert arbitrary objects to T
|
||||
else
|
||||
return ((Converter<T, U>) getConverter()).from(delegate.convert(object));
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
@Override
|
||||
public <X> DataType<X> asConvertedDataType(Converter<? super U, X> converter) {
|
||||
return super.asConvertedDataType(new ChainedConverterBinding(getBinding(), converter));
|
||||
}
|
||||
|
||||
/**
|
||||
* A binding that chains a new converter to an existing binding / converter.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
private static class ChainedConverterBinding<T, U1, U2> implements Binding<T, U2> {
|
||||
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -5120352678786683423L;
|
||||
|
||||
private final Binding<T, U1> delegate;
|
||||
private final Converter<U1, U2> suffix;
|
||||
private final Converter<T, U2> chained;
|
||||
|
||||
ChainedConverterBinding(Binding<T, U1> delegate, Converter<U1, U2> converter) {
|
||||
this.delegate = delegate;
|
||||
this.suffix = converter;
|
||||
this.chained = Converters.of(delegate.converter(), converter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Converter<T, U2> converter() {
|
||||
return chained;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sql(BindingSQLContext<U2> ctx) throws SQLException {
|
||||
delegate.sql(ctx.convert(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(BindingRegisterContext<U2> ctx) throws SQLException {
|
||||
delegate.register(ctx.convert(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(BindingSetStatementContext<U2> ctx) throws SQLException {
|
||||
delegate.set(ctx.convert(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(BindingSetSQLOutputContext<U2> ctx) throws SQLException {
|
||||
delegate.set(ctx.convert(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(BindingGetResultSetContext<U2> ctx) throws SQLException {
|
||||
delegate.get(ctx.convert(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(BindingGetStatementContext<U2> ctx) throws SQLException {
|
||||
delegate.get(ctx.convert(suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(BindingGetSQLInputContext<U2> ctx) throws SQLException {
|
||||
delegate.get(ctx.convert(suffix));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -44,6 +44,8 @@ import static org.jooq.impl.Tools.embeddedFields;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_LIST_ALREADY_INDENTED;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
@ -51,6 +53,7 @@ import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
/**
|
||||
@ -58,7 +61,9 @@ import org.jooq.tools.StringUtils;
|
||||
*/
|
||||
final class Val<T> extends AbstractParam<T> {
|
||||
|
||||
private static final long serialVersionUID = 6807729087019209084L;
|
||||
private static final long serialVersionUID = 6807729087019209084L;
|
||||
private static final JooqLogger log = JooqLogger.getLogger(Val.class);
|
||||
private static final ConcurrentHashMap<Class<?>, Object> legacyWarnings = new ConcurrentHashMap<>();
|
||||
|
||||
Val(T value, DataType<T> type) {
|
||||
super(value, type);
|
||||
@ -75,10 +80,22 @@ final class Val<T> extends AbstractParam<T> {
|
||||
/**
|
||||
* [#10438] Convert this bind value to a new type.
|
||||
*/
|
||||
<U> Val<U> convertTo(DataType<U> type) {
|
||||
Val<U> w = new Val<>(type.convert(getValue()), type, getParamName());
|
||||
w.setInline(isInline());
|
||||
return w;
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
final <U> Val<U> convertTo(DataType<U> type) {
|
||||
if (getDataType() instanceof DataTypeProxy) {
|
||||
if (((DataTypeProxy<?>) getDataType()).type instanceof LegacyConvertedDataType && type == SQLDataType.OTHER) {
|
||||
type = (DataType) ((DataTypeProxy<?>) getDataType()).type;
|
||||
|
||||
if (legacyWarnings.size() < 8 && legacyWarnings.put(type.getType(), "") == null)
|
||||
log.warn("Deprecation", "User-defined, converted data type " + type.getType() + " was registered statically, which will be unsupported in the future, see https://github.com/jOOQ/jOOQ/issues/9492. Please use explicit data types in generated code, or e.g. with DSL.val(Object, DataType), or DSL.inline(Object, DataType).", new SQLWarning("Static type registry usage"));
|
||||
}
|
||||
|
||||
Val<U> w = new Val<>(type.convert(getValue()), type, getParamName());
|
||||
w.setInline(isInline());
|
||||
return w;
|
||||
}
|
||||
else
|
||||
return (Val) this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
Reference in New Issue
Block a user