[jOOQ/jOOQ#9879] Added more generics to Generator and GeneratorContext
In order to implement pure functions of type Generator, we must make the GeneratorContext::table available to Generator implementations, including the usual type safety that allows for binding to the generated table type, which gives access to columns. This prevents having to capture this from the Generator, which isn't too clean (though it's still possible for those people who don't care)
This commit is contained in:
parent
4717560baa
commit
153762132f
@ -607,7 +607,7 @@ public interface DataType<T> extends Named {
|
||||
* This feature is implemented in commercial distributions only.
|
||||
*/
|
||||
@NotNull
|
||||
DataType<T> generatedAlwaysAs(Generator<T> generatedAlwaysAsValue);
|
||||
DataType<T> generatedAlwaysAs(Generator<?, ?, T> generatedAlwaysAsValue);
|
||||
|
||||
/**
|
||||
* Get the computed column expression of this data type, if any.
|
||||
@ -630,7 +630,7 @@ public interface DataType<T> extends Named {
|
||||
* This feature is implemented in commercial distributions only.
|
||||
*/
|
||||
@Nullable
|
||||
Generator<T> generatedAlwaysAsGenerator();
|
||||
Generator<?, ?, T> generatedAlwaysAsGenerator();
|
||||
|
||||
/**
|
||||
* Set the {@link #generationOption()} of the computed column expression to
|
||||
|
||||
@ -50,7 +50,7 @@ import java.util.function.Function;
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Generator<T> extends Function<GeneratorContext<T>, Field<T>>, Serializable {
|
||||
public interface Generator<R extends Record, X extends Table<R>, T> extends Function<GeneratorContext<R, X, T>, Field<T>>, Serializable {
|
||||
|
||||
/**
|
||||
* Whether this generator supports a given statement type.
|
||||
|
||||
@ -37,7 +37,6 @@
|
||||
*/
|
||||
package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@ -49,7 +48,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface GeneratorContext<T> extends Scope {
|
||||
public interface GeneratorContext<R extends Record, X extends Table<R>, T> extends Scope {
|
||||
|
||||
/**
|
||||
* The target table whose contents are being generated, or <code>null</code>
|
||||
* when the table is unknown / not applicable.
|
||||
*/
|
||||
@Nullable
|
||||
X table();
|
||||
|
||||
/**
|
||||
* The target field whose contents are being generated, or <code>null</code>
|
||||
|
||||
@ -103,6 +103,7 @@ import org.jooq.Result;
|
||||
import org.jooq.Row;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.XML;
|
||||
import org.jooq.impl.QOM.GenerationLocation;
|
||||
import org.jooq.impl.QOM.GenerationOption;
|
||||
@ -203,20 +204,20 @@ implements
|
||||
|
||||
@Override
|
||||
public final DataType<T> generatedAlwaysAs(Field<T> generatedAlwaysAsValue) {
|
||||
return generatedAlwaysAs(ctx -> generatedAlwaysAsValue);
|
||||
return generatedAlwaysAs((Generator<Record, Table<Record>, T>) t -> generatedAlwaysAsValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract DataType<T> generatedAlwaysAs(Generator<T> generatedAlwaysAsValue);
|
||||
public abstract DataType<T> generatedAlwaysAs(Generator<?, ?, T> generatedAlwaysAsValue);
|
||||
|
||||
@Override
|
||||
public final Field<T> generatedAlwaysAs() {
|
||||
Generator<T> s = generatedAlwaysAsGenerator();
|
||||
return s == null ? null : s.apply(new DefaultGeneratorContext(CONFIG, null, null));
|
||||
Generator<?, ?, T> s = generatedAlwaysAsGenerator();
|
||||
return s == null ? null : s.apply(new DefaultGeneratorContext(CONFIG, null, null, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract Generator<T> generatedAlwaysAsGenerator();
|
||||
public abstract Generator<?, ?, T> generatedAlwaysAsGenerator();
|
||||
|
||||
@Override
|
||||
public final DataType<T> stored() {
|
||||
|
||||
@ -73,7 +73,7 @@ abstract class AbstractDataTypeX<T> extends AbstractDataType<T> {
|
||||
Integer newLength,
|
||||
Nullability newNullability,
|
||||
boolean newReadonly,
|
||||
Generator<T> newGeneratedAlwaysAs,
|
||||
Generator<?, ?, T> newGeneratedAlwaysAs,
|
||||
GenerationOption newGenerationOption,
|
||||
GenerationLocation newGenerationLocation,
|
||||
Collation newCollation,
|
||||
@ -124,7 +124,7 @@ abstract class AbstractDataTypeX<T> extends AbstractDataType<T> {
|
||||
private static final JooqLogger logGeneratedAlwaysAs = JooqLogger.getLogger(AbstractDataTypeX.class, "generateAlwaysAs", 1);
|
||||
|
||||
@Override
|
||||
public final DataType<T> generatedAlwaysAs(Generator<T> g) {
|
||||
public final DataType<T> generatedAlwaysAs(Generator<?, ?, T> g) {
|
||||
if (g != null && !CONFIG.commercial())
|
||||
logGeneratedAlwaysAs.info("Computed columns", "Computed columns are a commercial only jOOQ feature. If you wish to profit from this feature, please upgrade to the jOOQ Professional Edition");
|
||||
|
||||
|
||||
@ -796,7 +796,7 @@ abstract class AbstractTable<R extends Record> extends AbstractNamed implements
|
||||
* @param type The data type of the field
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected static final <R extends Record, T, X, U> TableField<R, U> createField(Name name, DataType<T> type, Table<R> table, String comment, Converter<X, U> converter, Binding<T, X> binding, Generator<U> generator) {
|
||||
protected static final <R extends Record, TR extends Table<R>, T, X, U> TableField<R, U> createField(Name name, DataType<T> type, TR table, String comment, Converter<X, U> converter, Binding<T, X> binding, Generator<R, TR, U> generator) {
|
||||
Binding<T, U> actualBinding = DefaultBinding.newBinding(converter, type, binding);
|
||||
DataType<U> actualType =
|
||||
converter == null && binding == null
|
||||
|
||||
@ -76,7 +76,7 @@ final class ArrayDataType<T> extends DefaultDataType<T[]> {
|
||||
Integer length,
|
||||
Nullability nullability,
|
||||
boolean readonly,
|
||||
Generator<T[]> generatedAlwaysAs,
|
||||
Generator<?, ?, T[]> generatedAlwaysAs,
|
||||
GenerationOption generationOption,
|
||||
GenerationLocation generationLocation,
|
||||
Collation collation,
|
||||
@ -97,7 +97,7 @@ final class ArrayDataType<T> extends DefaultDataType<T[]> {
|
||||
Integer newLength,
|
||||
Nullability newNullability,
|
||||
boolean newReadonly,
|
||||
Generator<T[]> newGeneratedAlwaysAs,
|
||||
Generator<?, ?, T[]> newGeneratedAlwaysAs,
|
||||
GenerationOption newGenerationOption,
|
||||
GenerationLocation newGenerationLocation,
|
||||
Collation newCollation,
|
||||
|
||||
@ -93,6 +93,8 @@ package org.jooq.impl;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ final class ConvertedDataType<T, U> extends AbstractDataTypeX<U> {
|
||||
Integer newLength,
|
||||
Nullability newNullability,
|
||||
boolean newReadonly,
|
||||
Generator<U> newGeneratedAlwaysAs,
|
||||
Generator<?, ?, U> newGeneratedAlwaysAs,
|
||||
GenerationOption newGenerationOption,
|
||||
GenerationLocation newGenerationLocation,
|
||||
Collation newCollation,
|
||||
@ -210,8 +210,8 @@ final class ConvertedDataType<T, U> extends AbstractDataTypeX<U> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Generator<U> generatedAlwaysAsGenerator() {
|
||||
return (Generator<U>) delegate.generatedAlwaysAsGenerator();
|
||||
public final Generator<?, ?, U> generatedAlwaysAsGenerator() {
|
||||
return (Generator<?, ?, U>) delegate.generatedAlwaysAsGenerator();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -66,7 +66,7 @@ final class DataTypeProxy<T> extends AbstractDataType<T> {
|
||||
private final Integer overrideLength;
|
||||
private final Nullability overrideNullability;
|
||||
private final Boolean overrideReadonly;
|
||||
private final Generator<T> overrideGeneratedAlwaysAs;
|
||||
private final Generator<?, ?, T> overrideGeneratedAlwaysAs;
|
||||
private final GenerationOption overrideGenerationOption;
|
||||
private final GenerationLocation overrideGenerationLocation;
|
||||
private final Collation overrideCollation;
|
||||
@ -86,7 +86,7 @@ final class DataTypeProxy<T> extends AbstractDataType<T> {
|
||||
Integer overrideLength,
|
||||
Nullability overrideNullability,
|
||||
Boolean overrideReadonly,
|
||||
Generator<T> overrideGeneratedAlwaysAs,
|
||||
Generator<?, ?, T> overrideGeneratedAlwaysAs,
|
||||
GenerationOption overrideGenerationOption,
|
||||
GenerationLocation overrideGenerationLocation,
|
||||
Collation overrideCollation,
|
||||
@ -198,12 +198,12 @@ final class DataTypeProxy<T> extends AbstractDataType<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Generator<T> generatedAlwaysAsGenerator() {
|
||||
public final Generator<?, ?, T> generatedAlwaysAsGenerator() {
|
||||
return defaultIfNull(overrideGeneratedAlwaysAs, type.generatedAlwaysAsGenerator());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DataType<T> generatedAlwaysAs(Generator<T> g) {
|
||||
public final DataType<T> generatedAlwaysAs(Generator<?, ?, T> g) {
|
||||
return new DataTypeProxy<>(
|
||||
this,
|
||||
overridePrecision,
|
||||
|
||||
@ -259,7 +259,7 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
|
||||
|
||||
private final Nullability nullability;
|
||||
private final boolean readonly;
|
||||
private final Generator<T> generatedAlwaysAs;
|
||||
private final Generator<?, ?, T> generatedAlwaysAs;
|
||||
private final GenerationOption generationOption;
|
||||
private final GenerationLocation generationLocation;
|
||||
private final Collation collation;
|
||||
@ -334,7 +334,7 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
|
||||
this(dialect, sqlDataType, type, binding, qualifiedTypeName, typeName, castTypeName, precision, scale, length, nullability, false, null, GenerationOption.DEFAULT, GenerationLocation.SERVER, null, null, false, defaultValue);
|
||||
}
|
||||
|
||||
DefaultDataType(SQLDialect dialect, DataType<T> sqlDataType, Class<T> type, Binding<?, T> binding, Name qualifiedTypeName, String typeName, String castTypeName, Integer precision, Integer scale, Integer length, Nullability nullability, boolean readonly, Generator<T> generatedAlwaysAs, GenerationOption generationOption, GenerationLocation generationLocation, Collation collation, CharacterSet characterSet, boolean identity, Field<T> defaultValue) {
|
||||
DefaultDataType(SQLDialect dialect, DataType<T> sqlDataType, Class<T> type, Binding<?, T> binding, Name qualifiedTypeName, String typeName, String castTypeName, Integer precision, Integer scale, Integer length, Nullability nullability, boolean readonly, Generator<?, ?, T> generatedAlwaysAs, GenerationOption generationOption, GenerationLocation generationLocation, Collation collation, CharacterSet characterSet, boolean identity, Field<T> defaultValue) {
|
||||
super(qualifiedTypeName, NO_COMMENT);
|
||||
|
||||
// Initialise final instance members
|
||||
@ -401,7 +401,7 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
|
||||
Integer newLength,
|
||||
Nullability newNullability,
|
||||
boolean newReadonly,
|
||||
Generator<T> newGeneratedAlwaysAs,
|
||||
Generator<?, ?, T> newGeneratedAlwaysAs,
|
||||
GenerationOption newGenerationOption,
|
||||
GenerationLocation newGenerationLocation,
|
||||
Collation newCollation,
|
||||
@ -436,7 +436,7 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
|
||||
Integer length,
|
||||
Nullability nullability,
|
||||
boolean readonly,
|
||||
Generator<T> generatedAlwaysAs,
|
||||
Generator<?, ?, T> generatedAlwaysAs,
|
||||
GenerationOption generationOption,
|
||||
GenerationLocation generationLocation,
|
||||
Collation collation,
|
||||
@ -500,7 +500,7 @@ public class DefaultDataType<T> extends AbstractDataTypeX<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Generator<T> generatedAlwaysAsGenerator() {
|
||||
public final Generator<?, ?, T> generatedAlwaysAsGenerator() {
|
||||
return generatedAlwaysAs;
|
||||
}
|
||||
|
||||
|
||||
@ -41,22 +41,31 @@ import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.GeneratorContext;
|
||||
import org.jooq.GeneratorStatementType;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Table;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class DefaultGeneratorContext<T> extends AbstractScope implements GeneratorContext<T> {
|
||||
final class DefaultGeneratorContext<R extends Record, X extends Table<R>, T> extends AbstractScope implements GeneratorContext<R, X, T> {
|
||||
|
||||
final X table;
|
||||
final Field<T> field;
|
||||
final GeneratorStatementType statementType;
|
||||
|
||||
DefaultGeneratorContext(Configuration configuration, Field<T> field, GeneratorStatementType statementType) {
|
||||
DefaultGeneratorContext(Configuration configuration, X table, Field<T> field, GeneratorStatementType statementType) {
|
||||
super(configuration);
|
||||
|
||||
this.table = table;
|
||||
this.field = field;
|
||||
this.statementType = statementType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final X table() {
|
||||
return table;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Field<T> field() {
|
||||
return field;
|
||||
|
||||
@ -88,6 +88,7 @@ import org.jooq.RenderContext.CastMode;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.Select;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.conf.WriteIfReadonly;
|
||||
import org.jooq.exception.DataTypeException;
|
||||
import org.jooq.impl.AbstractStoreQuery.UnknownField;
|
||||
@ -299,6 +300,11 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ final class MultisetDataType<R extends Record> extends DefaultDataType<Result<R>
|
||||
Integer length,
|
||||
Nullability nullability,
|
||||
boolean readonly,
|
||||
Generator<Result<R>> generatedAlwaysAs,
|
||||
Generator<?, ?, Result<R>> generatedAlwaysAs,
|
||||
GenerationOption generationOption,
|
||||
GenerationLocation generationLocation,
|
||||
Collation collation,
|
||||
@ -110,7 +110,7 @@ final class MultisetDataType<R extends Record> extends DefaultDataType<Result<R>
|
||||
Integer newLength,
|
||||
Nullability newNullability,
|
||||
boolean newReadonly,
|
||||
Generator<Result<R>> newGeneratedAlwaysAs,
|
||||
Generator<?, ?, Result<R>> newGeneratedAlwaysAs,
|
||||
GenerationOption newGenerationOption,
|
||||
GenerationLocation newGenerationLocation,
|
||||
Collation newCollation,
|
||||
|
||||
@ -89,7 +89,7 @@ final class RecordDataType<R extends Record> extends DefaultDataType<R> {
|
||||
Integer length,
|
||||
Nullability nullability,
|
||||
boolean readonly,
|
||||
Generator<R> generatedAlwaysAs,
|
||||
Generator<?, ?, R> generatedAlwaysAs,
|
||||
GenerationOption generationOption,
|
||||
GenerationLocation generationLocation,
|
||||
Collation collation,
|
||||
@ -110,7 +110,7 @@ final class RecordDataType<R extends Record> extends DefaultDataType<R> {
|
||||
Integer newLength,
|
||||
Nullability newNullability,
|
||||
boolean newReadonly,
|
||||
Generator<R> newGeneratedAlwaysAs,
|
||||
Generator<?, ?, R> newGeneratedAlwaysAs,
|
||||
GenerationOption newGenerationOption,
|
||||
GenerationLocation newGenerationLocation,
|
||||
Collation newCollation,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user