[jOOQ/jOOQ#228] Enhance API to provide access to UDT members - WIP
This commit is contained in:
parent
301b9749f4
commit
c466d68a85
@ -71,6 +71,7 @@ abstract class AbstractGenerator implements Generator {
|
||||
boolean generateDeprecationOnUnknownTypes = true;
|
||||
boolean generateIndexes = true;
|
||||
boolean generateRelations = true;
|
||||
boolean generateUDTPaths = true;
|
||||
boolean generateImplicitJoinPathsToOne = true;
|
||||
boolean generateImplicitJoinPathsToMany = true;
|
||||
boolean generateImplicitJoinPathTableSubtypes = true;
|
||||
@ -306,6 +307,16 @@ abstract class AbstractGenerator implements Generator {
|
||||
this.generateRelations = generateRelations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateUDTPaths() {
|
||||
return generateUDTPaths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenerateUDTPaths(boolean generateUDTPaths) {
|
||||
this.generateUDTPaths = generateUDTPaths;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateImplicitJoinPathsToOne() {
|
||||
return generateImplicitJoinPathsToOne && generateRelations();
|
||||
|
||||
@ -66,6 +66,7 @@ import org.jooq.impl.SchemaImpl;
|
||||
import org.jooq.impl.TableImpl;
|
||||
import org.jooq.impl.TableRecordImpl;
|
||||
import org.jooq.impl.UDTImpl;
|
||||
import org.jooq.impl.UDTPathTableFieldImpl;
|
||||
import org.jooq.impl.UDTRecordImpl;
|
||||
import org.jooq.impl.UpdatableRecordImpl;
|
||||
import org.jooq.meta.ArrayDefinition;
|
||||
@ -335,14 +336,15 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
}
|
||||
else if (definition instanceof TableDefinition t) {
|
||||
switch (mode) {
|
||||
case DAO: return DAOImpl.class.getName();
|
||||
case RECORD: return (t.getPrimaryKey() != null ? UpdatableRecordImpl.class : TableRecordImpl.class).getName();
|
||||
case DAO: return DAOImpl.class.getName();
|
||||
case RECORD: return (t.getPrimaryKey() != null ? UpdatableRecordImpl.class : TableRecordImpl.class).getName();
|
||||
case DEFAULT: return TableImpl.class.getName();
|
||||
}
|
||||
}
|
||||
else if (definition instanceof UDTDefinition) {
|
||||
switch (mode) {
|
||||
case RECORD: return UDTRecordImpl.class.getName();
|
||||
case PATH: return UDTPathTableFieldImpl.class.getName();
|
||||
case RECORD: return UDTRecordImpl.class.getName();
|
||||
case DEFAULT: return UDTImpl.class.getName();
|
||||
}
|
||||
}
|
||||
@ -464,7 +466,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
if (!(definition instanceof SchemaDefinition)) {
|
||||
|
||||
// Some definitions have their dedicated subpackages, e.g. "tables", "routines"
|
||||
String subPackage = getSubPackage(definition);
|
||||
String subPackage = getSubPackage(definition, mode);
|
||||
if (!StringUtils.isBlank(subPackage)) {
|
||||
sb.append(".");
|
||||
sb.append(subPackage);
|
||||
@ -547,7 +549,7 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private String getSubPackage(Definition definition) {
|
||||
private String getSubPackage(Definition definition, Mode mode) {
|
||||
if (definition instanceof TableDefinition)
|
||||
return "tables";
|
||||
|
||||
@ -561,6 +563,8 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
// [#330] [#6529] A UDT inside of a package is a PL/SQL RECORD type
|
||||
if (u.getPackage() != null)
|
||||
return "packages." + getJavaIdentifier(u.getPackage()).toLowerCase(targetLocale) + ".udt";
|
||||
else if (mode == Mode.PATH)
|
||||
return "udt.paths";
|
||||
else
|
||||
return "udt";
|
||||
}
|
||||
|
||||
@ -736,9 +736,11 @@ public class GenerationTool {
|
||||
generator.setGenerateIndexes(g.getGenerate().isIndexes());
|
||||
if (g.getGenerate().isRelations() != null)
|
||||
generator.setGenerateRelations(g.getGenerate().isRelations());
|
||||
if (g.getGenerate().isImplicitJoinPathsToMany() != null)
|
||||
generator.setGenerateImplicitJoinPathsToOne(g.getGenerate().isImplicitJoinPathsToOne());
|
||||
if (g.getGenerate().isUdtPaths() != null)
|
||||
generator.setGenerateUDTPaths(g.getGenerate().isUdtPaths());
|
||||
if (g.getGenerate().isImplicitJoinPathsToOne() != null)
|
||||
generator.setGenerateImplicitJoinPathsToOne(g.getGenerate().isImplicitJoinPathsToOne());
|
||||
if (g.getGenerate().isImplicitJoinPathsToMany() != null)
|
||||
generator.setGenerateImplicitJoinPathsToMany(g.getGenerate().isImplicitJoinPathsToMany());
|
||||
if (g.getGenerate().isImplicitJoinPathTableSubtypes() != null)
|
||||
generator.setGenerateImplicitJoinPathTableSubtypes(g.getGenerate().isImplicitJoinPathTableSubtypes());
|
||||
|
||||
@ -124,6 +124,16 @@ public interface Generator {
|
||||
*/
|
||||
void setGenerateRelations(boolean generateRelations);
|
||||
|
||||
/**
|
||||
* Whether to generate UDT path expressions on tables and UDTs.
|
||||
*/
|
||||
boolean generateUDTPaths();
|
||||
|
||||
/**
|
||||
* Whether to generate UDT path expressions on tables and UDTs.
|
||||
*/
|
||||
void setGenerateUDTPaths(boolean generateUDTPaths);
|
||||
|
||||
/**
|
||||
* Whether implicit join path constructors on generated tables for outgoing
|
||||
* foreign key relationships (to-one relationships) should be generated.
|
||||
|
||||
@ -567,9 +567,9 @@ public interface GeneratorStrategy {
|
||||
DOMAIN,
|
||||
|
||||
/**
|
||||
* The path mode. This is used when a {@link ForeignKeyDefinition} or an
|
||||
* {@link InverseForeignKeyDefinition} is used to generate a path
|
||||
* expression.
|
||||
* The path mode. This is used when a {@link ForeignKeyDefinition}, an
|
||||
* {@link InverseForeignKeyDefinition}, or a {@link UDTDefinition} is
|
||||
* used to generate a path expression.
|
||||
*/
|
||||
PATH
|
||||
|
||||
|
||||
@ -95,8 +95,10 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jooq.AggregateFunction;
|
||||
import org.jooq.Binding;
|
||||
import org.jooq.Catalog;
|
||||
import org.jooq.Check;
|
||||
import org.jooq.Comment;
|
||||
import org.jooq.Condition;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Constants;
|
||||
@ -122,6 +124,7 @@ import org.jooq.PlainSQL;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordQualifier;
|
||||
import org.jooq.Records;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Row;
|
||||
@ -3171,6 +3174,10 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
for (UDTDefinition udt : database.getUDTs(schema)) {
|
||||
try {
|
||||
generateUDT(schema, udt);
|
||||
|
||||
// [#228] Package UDTs can't be used as path expressions in SQL
|
||||
if (generateUDTPaths() && udt.getPackage() == null)
|
||||
generateUDTPath(schema, udt);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.error("Error while generating udt " + udt, e);
|
||||
@ -3349,6 +3356,92 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
printClassJavadoc(out, "The udt <code>" + udt.getQualifiedInputName() + "</code>.");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
protected void generateUDTPath(SchemaDefinition schema, UDTDefinition udt) {
|
||||
JavaWriter out = newJavaWriter(getFile(udt, Mode.PATH));
|
||||
out.refConflicts(getStrategy().getJavaIdentifiers(udt.getAttributes()));
|
||||
|
||||
log.info("Generating UDT Path", out.file().getName());
|
||||
|
||||
if (log.isDebugEnabled())
|
||||
for (AttributeDefinition attribute : udt.getAttributes())
|
||||
log.debug("With attribute", "name=" + attribute.getOutputName() + ", matching type names=" + attribute.getDefinedType().getMatchNames());
|
||||
|
||||
generateUDTPath(udt, out);
|
||||
closeJavaWriter(out);
|
||||
}
|
||||
|
||||
protected void generateUDTPath(UDTDefinition udt, JavaWriter out) {
|
||||
final String className = getStrategy().getJavaClassName(udt, Mode.PATH);
|
||||
final String recordType = out.ref(getStrategy().getFullJavaClassName(udt, Mode.RECORD));
|
||||
final String classExtends = out.ref(getStrategy().getJavaClassExtends(udt, Mode.PATH));
|
||||
final List<String> interfaces = out.ref(getStrategy().getJavaClassImplements(udt, Mode.PATH));
|
||||
final String udtId = out.ref(getStrategy().getFullJavaIdentifier(udt), 2);
|
||||
|
||||
printPackage(out, udt, Mode.PATH);
|
||||
|
||||
generateUDTPathClassJavadoc(udt, out);
|
||||
printClassAnnotations(out, udt, Mode.PATH);
|
||||
|
||||
out.println("%sclass %s<R extends %s, T> extends %s<R, %s, T>[[before= implements ][%s]] {",
|
||||
visibility(), className, Record.class, classExtends, recordType, interfaces);
|
||||
out.printSerial();
|
||||
|
||||
for (AttributeDefinition attribute : udt.getAttributes()) {
|
||||
final String attrTypeFull = getJavaType(attribute.getType(resolver(out)), out);
|
||||
final String attrType = out.ref(attrTypeFull);
|
||||
final String attrTypeRef = getJavaTypeReference(attribute.getDatabase(), attribute.getType(resolver(out)), out);
|
||||
final String attrId = out.ref(getStrategy().getJavaIdentifier(attribute), 2);
|
||||
final String attrName = attribute.getName();
|
||||
final List<String> converter = out.ref(list(attribute.getType(resolver(out)).getConverter()));
|
||||
final List<String> binding = out.ref(list(attribute.getType(resolver(out)).getBinding()));
|
||||
|
||||
if (!printDeprecationIfUnknownType(out, attrTypeFull))
|
||||
out.javadoc("The attribute <code>%s</code>.[[before= ][%s]]", attribute.getQualifiedOutputName(), list(escapeEntities(comment(attribute))));
|
||||
|
||||
if (attribute.getType().isUDT() && !attribute.getDatabase().isArrayType(attrTypeFull)) {
|
||||
final SchemaDefinition attrUdtSchema = attribute.getDatabase().getSchema(attribute.getType().getQualifiedUserType().qualifier().last());
|
||||
final UDTDefinition attrUdt = attribute.getDatabase().getUDT(attrUdtSchema, attribute.getType().getUserType());
|
||||
final String attrPathType = out.ref(getStrategy().getFullJavaClassName(attrUdt, Mode.PATH));
|
||||
|
||||
out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");",
|
||||
visibility(), attrPathType, recordType, attrType, attrId, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, converter, binding);
|
||||
}
|
||||
else {
|
||||
final String attrPathType = out.ref(UDTField.class);
|
||||
|
||||
out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");",
|
||||
visibility(), attrPathType, recordType, attrType, attrId, Internal.class, DSL.class, escapeString(attrName), attrTypeRef, escapeString(""), attrPathType, converter, binding);
|
||||
}
|
||||
}
|
||||
|
||||
out.println();
|
||||
out.println("%s%s(%s name, %s<T> type, %s<R> qualifier, %s comment, %s<?, T> binding) {",
|
||||
visibility(), className, Name.class, DataType.class, RecordQualifier.class, Comment.class, Binding.class);
|
||||
out.println("super(name, type, qualifier, %s, comment, binding);", udtId);
|
||||
out.println("}");
|
||||
|
||||
generateUDTPathClassFooter(udt, out);
|
||||
out.println("}");
|
||||
closeJavaWriter(out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide udt class footer code.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void generateUDTPathClassFooter(UDTDefinition udt, JavaWriter out) {}
|
||||
|
||||
/**
|
||||
* Subclasses may override this method to provide their own Javadoc.
|
||||
*/
|
||||
protected void generateUDTPathClassJavadoc(UDTDefinition udt, JavaWriter out) {
|
||||
if (generateCommentsOnUDTs())
|
||||
printClassJavadoc(out, udt);
|
||||
else
|
||||
printClassJavadoc(out, "The udt path for <code>" + udt.getQualifiedInputName() + "</code>.");
|
||||
}
|
||||
|
||||
protected void generateUDTPojos(SchemaDefinition schema) {
|
||||
log.info("Generating UDT POJOs");
|
||||
|
||||
@ -6316,8 +6409,21 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
String isStatic = generateInstanceFields() ? "" : "static ";
|
||||
String tableRef = generateInstanceFields() ? "this" : out.ref(getStrategy().getJavaIdentifier(table), 2);
|
||||
|
||||
out.println("%s%sfinal %s<%s, %s> %s = createField(%s.name(\"%s\"), %s, %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + converterTemplate(generator) + ");",
|
||||
columnVisibility, isStatic, TableField.class, recordType, columnType, columnId, DSL.class, columnName, columnTypeRef, tableRef, escapeString(comment(column)), converter, binding, generator);
|
||||
if (generateInstanceFields()
|
||||
&& generateUDTPaths()
|
||||
&& column.getType().isUDT()
|
||||
&& !column.getDatabase().isArrayType(columnTypeFull)
|
||||
) {
|
||||
final SchemaDefinition columnUdtSchema = column.getDatabase().getSchema(column.getType().getQualifiedUserType().qualifier().last());
|
||||
final UDTDefinition columnUdt = column.getDatabase().getUDT(columnUdtSchema, column.getType().getUserType());
|
||||
final String columnPathType = out.ref(getStrategy().getFullJavaClassName(columnUdt, Mode.PATH));
|
||||
|
||||
out.println("%sfinal %s<%s, %s> %s = %s.createUDTPathTableField(%s.name(\"%s\"), %s, this, \"%s\", %s.class" + converterTemplate(converter) + converterTemplate(binding) + ");",
|
||||
visibility(), columnPathType, recordType, columnType, columnId, Internal.class, DSL.class, escapeString(columnName), columnTypeRef, escapeString(comment(column)), columnPathType, converter, binding);
|
||||
}
|
||||
else
|
||||
out.println("%s%sfinal %s<%s, %s> %s = createField(%s.name(\"%s\"), %s, %s, \"%s\"" + converterTemplate(converter) + converterTemplate(binding) + converterTemplate(generator) + ");",
|
||||
columnVisibility, isStatic, TableField.class, recordType, columnType, columnId, DSL.class, columnName, columnTypeRef, tableRef, escapeString(comment(column)), converter, binding, generator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -703,7 +703,7 @@ fun InformationSchema.indexes(block: MutableList<org.jooq.util.xml.jaxb.Index>.(
|
||||
}
|
||||
|
||||
@JvmName("mutableListIndex")
|
||||
fun MutableList<org.jooq.util.xml.jaxb.Index>.indexe(block: org.jooq.util.xml.jaxb.Index.() -> Unit) {
|
||||
fun MutableList<org.jooq.util.xml.jaxb.Index>.index(block: org.jooq.util.xml.jaxb.Index.() -> Unit) {
|
||||
val e = org.jooq.util.xml.jaxb.Index()
|
||||
block(e)
|
||||
add(e)
|
||||
|
||||
@ -99,7 +99,7 @@ fun Matchers.indexes(block: MutableList<MatchersIndexType>.() -> Unit) {
|
||||
}
|
||||
|
||||
@JvmName("mutableListMatchersIndexType")
|
||||
fun MutableList<MatchersIndexType>.indexe(block: MatchersIndexType.() -> Unit) {
|
||||
fun MutableList<MatchersIndexType>.index(block: MatchersIndexType.() -> Unit) {
|
||||
val e = MatchersIndexType()
|
||||
block(e)
|
||||
add(e)
|
||||
|
||||
@ -37,6 +37,8 @@ public class Generate implements Serializable, XMLAppendable
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean sequenceFlags = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean udtPaths = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean implicitJoinPathsToOne = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean implicitJoinPathsToMany = true;
|
||||
@ -332,6 +334,30 @@ public class Generate implements Serializable, XMLAppendable
|
||||
this.sequenceFlags = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate UDT path expressions on tables and on UDTs.
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isUdtPaths() {
|
||||
return udtPaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the udtPaths property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setUdtPaths(Boolean value) {
|
||||
this.udtPaths = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate implicit join path constructors on generated tables for outgoing foreign key relationships (to-one relationships)
|
||||
*
|
||||
@ -2892,6 +2918,11 @@ public class Generate implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withUdtPaths(Boolean value) {
|
||||
setUdtPaths(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withImplicitJoinPathsToOne(Boolean value) {
|
||||
setImplicitJoinPathsToOne(value);
|
||||
return this;
|
||||
@ -3490,6 +3521,7 @@ public class Generate implements Serializable, XMLAppendable
|
||||
builder.append("indexes", indexes);
|
||||
builder.append("relations", relations);
|
||||
builder.append("sequenceFlags", sequenceFlags);
|
||||
builder.append("udtPaths", udtPaths);
|
||||
builder.append("implicitJoinPathsToOne", implicitJoinPathsToOne);
|
||||
builder.append("implicitJoinPathsToMany", implicitJoinPathsToMany);
|
||||
builder.append("implicitJoinPathTableSubtypes", implicitJoinPathTableSubtypes);
|
||||
@ -3646,6 +3678,15 @@ public class Generate implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (udtPaths == null) {
|
||||
if (other.udtPaths!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!udtPaths.equals(other.udtPaths)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (implicitJoinPathsToOne == null) {
|
||||
if (other.implicitJoinPathsToOne!= null) {
|
||||
return false;
|
||||
@ -4628,6 +4669,7 @@ public class Generate implements Serializable, XMLAppendable
|
||||
result = ((prime*result)+((indexes == null)? 0 :indexes.hashCode()));
|
||||
result = ((prime*result)+((relations == null)? 0 :relations.hashCode()));
|
||||
result = ((prime*result)+((sequenceFlags == null)? 0 :sequenceFlags.hashCode()));
|
||||
result = ((prime*result)+((udtPaths == null)? 0 :udtPaths.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathsToOne == null)? 0 :implicitJoinPathsToOne.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathsToMany == null)? 0 :implicitJoinPathsToMany.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathTableSubtypes == null)? 0 :implicitJoinPathTableSubtypes.hashCode()));
|
||||
|
||||
@ -2166,6 +2166,10 @@ This is a prerequisite for various advanced features]]></jxb:javadoc></jxb:prope
|
||||
<element name="sequenceFlags" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Sequence flags should be generated and used.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="udtPaths" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Generate UDT path expressions on tables and on UDTs.]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="implicitJoinPathsToOne" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Generate implicit join path constructors on generated tables for outgoing foreign key relationships (to-one relationships)]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
|
||||
package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A field contained in a UDT.
|
||||
@ -54,5 +55,6 @@ public interface UDTField<R extends UDTRecord<R>, T> extends Field<T> {
|
||||
/**
|
||||
* @return The UDT this field is contained in
|
||||
*/
|
||||
@Nullable
|
||||
UDT<R> getUDT();
|
||||
}
|
||||
|
||||
67
jOOQ/src/main/java/org/jooq/UDTPathField.java
Normal file
67
jOOQ/src/main/java/org/jooq/UDTPathField.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* https://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: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A field dereferenced from a UDT path.
|
||||
* <p>
|
||||
* Instances of this type cannot be created directly. They are available from
|
||||
* generated code.
|
||||
*
|
||||
* @param <R> The record type
|
||||
* @param <T> The field type
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface UDTPathField<R extends Record, U extends UDTRecord<U>, T> extends UDTField<U, T> {
|
||||
|
||||
/**
|
||||
* @return The UDT path this field is contained in.
|
||||
*/
|
||||
@NotNull
|
||||
RecordQualifier<R> getQualifier();
|
||||
|
||||
/**
|
||||
* @return The UDT path represented by this field.
|
||||
*/
|
||||
@NotNull
|
||||
RecordQualifier<U> asQualifier();
|
||||
|
||||
}
|
||||
61
jOOQ/src/main/java/org/jooq/UDTPathTableField.java
Normal file
61
jOOQ/src/main/java/org/jooq/UDTPathTableField.java
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* https://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: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A field dereferenced from a UDT path.
|
||||
* <p>
|
||||
* Instances of this type cannot be created directly. They are available from
|
||||
* generated code.
|
||||
*
|
||||
* @param <R> The record type
|
||||
* @param <T> The field type
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface UDTPathTableField<R extends Record, U extends UDTRecord<U>, T> extends TableField<R, T>, UDTPathField<R, U, T> {
|
||||
|
||||
/**
|
||||
* @return The UDT path this field is contained in.
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
RecordQualifier<R> getQualifier();
|
||||
}
|
||||
@ -52,7 +52,6 @@ import static org.jooq.conf.WriteIfReadonly.IGNORE;
|
||||
import static org.jooq.conf.WriteIfReadonly.THROW;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.select;
|
||||
import static org.jooq.impl.FieldMapsForInsert.toSQLInsertSelect;
|
||||
import static org.jooq.impl.Keywords.K_DEFAULT_VALUES;
|
||||
import static org.jooq.impl.Keywords.K_VALUES;
|
||||
import static org.jooq.impl.QueryPartCollectionView.wrap;
|
||||
@ -64,6 +63,7 @@ import static org.jooq.impl.Tools.flattenCollection;
|
||||
import static org.jooq.impl.Tools.flattenFieldOrRows;
|
||||
import static org.jooq.impl.Tools.lazy;
|
||||
import static org.jooq.impl.Tools.row0;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_STORE_ASSIGNMENT;
|
||||
|
||||
import java.util.AbstractList;
|
||||
import java.util.AbstractMap;
|
||||
@ -754,7 +754,7 @@ final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImple
|
||||
fields = keysFlattened(ctx, GeneratorStatementType.INSERT);
|
||||
|
||||
if (!fields.isEmpty())
|
||||
ctx.sql(" (").visit(wrap(fields).qualify(false)).sql(')');
|
||||
ctx.data(DATA_STORE_ASSIGNMENT, true, c -> c.sql(" (").visit(wrap(fields).qualify(false)).sql(')'));
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ import org.jooq.Domain;
|
||||
import org.jooq.EmbeddableRecord;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Generator;
|
||||
import org.jooq.Identity;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.InverseForeignKey;
|
||||
@ -79,6 +80,7 @@ import org.jooq.Queries;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordQualifier;
|
||||
// ...
|
||||
// ...
|
||||
import org.jooq.Result;
|
||||
@ -95,11 +97,16 @@ import org.jooq.TableField;
|
||||
// ...
|
||||
// ...
|
||||
import org.jooq.UDT;
|
||||
import org.jooq.UDTField;
|
||||
import org.jooq.UDTPathField;
|
||||
import org.jooq.UDTPathTableField;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.UniqueKey;
|
||||
// ...
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.exception.DataTypeException;
|
||||
import org.jooq.impl.QOM.CreateTable;
|
||||
import org.jooq.impl.QOM.GenerationLocation;
|
||||
// ...
|
||||
// ...
|
||||
|
||||
@ -118,6 +125,222 @@ import org.reactivestreams.Subscription;
|
||||
@org.jooq.Internal
|
||||
public final class Internal {
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, P extends UDTPathTableField<R, UR, T>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
Table<R> table,
|
||||
Class<P> returnType
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, null, returnType, null, null, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, P extends UDTPathTableField<R, UR, T>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
Table<R> table,
|
||||
String comment,
|
||||
Class<P> returnType
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, null, null, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, U, P extends UDTPathTableField<R, UR, U>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
Table<R> table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Converter<T, U> converter
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, converter, null, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, U, P extends UDTPathTableField<R, UR, U>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
Table<R> table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Binding<T, U> binding
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, null, binding, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, X, U, P extends UDTPathTableField<R, UR, U>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
Table<R> table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Converter<X, U> converter,
|
||||
Binding<T, X> binding
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, converter, binding, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, TR extends Table<R>, UR extends UDTRecord<UR>, T, P extends UDTPathTableField<R, UR, T>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
TR table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Generator<R, TR, T> generator
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, null, null, generator);
|
||||
}
|
||||
|
||||
public static final <R extends Record, TR extends Table<R>, UR extends UDTRecord<UR>, T, U, P extends UDTPathTableField<R, UR, U>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
TR table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Converter<T, U> converter,
|
||||
Generator<R, TR, U> generator
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, converter, null, generator);
|
||||
}
|
||||
|
||||
public static final <R extends Record, TR extends Table<R>, UR extends UDTRecord<UR>, T, U, P extends UDTPathTableField<R, UR, U>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
TR table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Binding<T, U> binding,
|
||||
Generator<R, TR, U> generator
|
||||
) {
|
||||
return createUDTPathTableField(name, type, table, comment, returnType, null, binding, generator);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static final <R extends Record, TR extends Table<R>, UR extends UDTRecord<UR>, T, X, U, P extends UDTPathTableField<R, UR, U>> P createUDTPathTableField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
TR table,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
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
|
||||
? (DataType<U>) type
|
||||
: type.asConvertedDataType(actualBinding);
|
||||
|
||||
if (generator != null)
|
||||
actualType = actualType.generatedAlwaysAs(generator).generationLocation(GenerationLocation.CLIENT);
|
||||
|
||||
// [#5999] TODO: Allow for user-defined Names
|
||||
try {
|
||||
P tableField = newInstance(name, table, null, comment, returnType, actualBinding, actualType);
|
||||
|
||||
// [#1199] The public API of Table returns immutable field lists
|
||||
if (table instanceof TableImpl<?> t)
|
||||
t.fields.add(tableField);
|
||||
|
||||
return tableField;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new DataTypeException("Cannot instantiate " + returnType + ".", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, P extends UDTField<UR, T>> P createUDTPathField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
UDTPathField<R, UR, ?> qualifier,
|
||||
Class<P> returnType
|
||||
) {
|
||||
return createUDTPathField(name, type, qualifier, null, returnType, null, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, P extends UDTField<UR, T>> P createUDTPathField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
UDTPathField<R, UR, ?> qualifier,
|
||||
String comment,
|
||||
Class<P> returnType
|
||||
) {
|
||||
return createUDTPathField(name, type, qualifier, comment, returnType, null, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, U, P extends UDTField<UR, U>> P createUDTPathField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
UDTPathField<R, UR, ?> qualifier,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Converter<T, U> converter
|
||||
) {
|
||||
return createUDTPathField(name, type, qualifier, comment, returnType, converter, null);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, U, P extends UDTField<UR, U>> P createUDTPathField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
UDTPathField<R, UR, ?> qualifier,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Binding<T, U> binding
|
||||
) {
|
||||
return createUDTPathField(name, type, qualifier, comment, returnType, null, binding);
|
||||
}
|
||||
|
||||
public static final <R extends Record, UR extends UDTRecord<UR>, T, X, U, P extends UDTField<UR, U>> P createUDTPathField(
|
||||
Name name,
|
||||
DataType<T> type,
|
||||
UDTPathField<R, UR, ?> qualifier,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Converter<X, U> converter,
|
||||
Binding<T, X> binding
|
||||
) {
|
||||
Binding<T, U> actualBinding = DefaultBinding.newBinding(converter, type, binding);
|
||||
DataType<U> actualType =
|
||||
converter == null && binding == null
|
||||
? (DataType<U>) type
|
||||
: type.asConvertedDataType(actualBinding);
|
||||
|
||||
// [#5999] TODO: Allow for user-defined Names
|
||||
try {
|
||||
|
||||
// [#228] While it would be cleaner to pass around a Function5 constructor reference,
|
||||
// chances are that the cost on compilation speed is significantly higher than
|
||||
// if we just use reflection
|
||||
return newInstance(name, null, qualifier, comment, returnType, actualBinding, actualType);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new DataTypeException("Cannot instantiate " + returnType + ".", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <R extends Record, UR extends UDTRecord<UR>, T, X, U, P extends UDTField<UR, U>> P newInstance(
|
||||
Name name,
|
||||
RecordQualifier<R> qualifier,
|
||||
UDTPathField<R, ?, ?> path,
|
||||
String comment,
|
||||
Class<P> returnType,
|
||||
Binding<T, U> actualBinding,
|
||||
DataType<U> actualType
|
||||
) throws Exception {
|
||||
|
||||
// [#228] This case only happens in generated UDTPath types, never in generated Table types
|
||||
if (returnType == UDTField.class)
|
||||
return (P) new UDTPathFieldImpl<>(name, actualType, path.asQualifier(), path.getUDT(), DSL.comment(comment), actualBinding);
|
||||
|
||||
// [#228] While it would be cleaner to pass around a Function5 constructor reference,
|
||||
// chances are that the cost on compilation speed is significantly higher than
|
||||
// if we just use reflection
|
||||
else
|
||||
return returnType
|
||||
.getConstructor(Name.class, DataType.class, RecordQualifier.class, Comment.class, Binding.class)
|
||||
.newInstance(name, actualType, qualifier == null ? path.asQualifier() : qualifier, DSL.comment(comment), actualBinding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for embeddable types.
|
||||
*/
|
||||
|
||||
@ -78,7 +78,7 @@ import org.jooq.tools.StringUtils;
|
||||
*/
|
||||
final class TableFieldImpl<R extends Record, T>
|
||||
extends
|
||||
AbstractField<T>
|
||||
AbstractField<T>
|
||||
implements
|
||||
TableField<R, T>,
|
||||
SimpleQueryPart,
|
||||
@ -201,11 +201,15 @@ implements
|
||||
}
|
||||
|
||||
private final void accept1(Context<?> ctx) {
|
||||
ctx.data(DATA_OMIT_CLAUSE_EVENT_EMISSION, true, c -> {
|
||||
if (c.qualify() && getTable() != null && !FALSE.equals(ctx.data(DATA_RENDER_TABLE)))
|
||||
c.visit(getTable()).sql('.');
|
||||
accept2(ctx, getTable(), getUnqualifiedName());
|
||||
}
|
||||
|
||||
c.visit(getUnqualifiedName());
|
||||
static final void accept2(Context<?> ctx, Table<?> table, Name unqualifiedName) {
|
||||
ctx.data(DATA_OMIT_CLAUSE_EVENT_EMISSION, true, c -> {
|
||||
if (c.qualify() && table != null && !FALSE.equals(ctx.data(DATA_RENDER_TABLE)))
|
||||
c.visit(table).sql('.');
|
||||
|
||||
c.visit(unqualifiedName);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -658,8 +658,14 @@ final class Tools {
|
||||
DATA_PARSE_ON_CONFLICT,
|
||||
|
||||
/**
|
||||
* [#13808] We're in a store assignment context (e.g.
|
||||
* <code>UPDATE</code> or assignment statement).
|
||||
* [#228] [#13808] We're in a store assignment context.
|
||||
* <p>
|
||||
* This includes e.g.
|
||||
* <ul>
|
||||
* <li><code>INSERT</code> columns list.</li>
|
||||
* <li><code>UPDATE … SET</code> clause.</li>
|
||||
* <li>The procedural assignment statement.</li>
|
||||
* </ul>
|
||||
*/
|
||||
DATA_STORE_ASSIGNMENT,
|
||||
|
||||
@ -668,7 +674,6 @@ final class Tools {
|
||||
* not the query itself.
|
||||
*/
|
||||
DATA_RENDER_IMPLICIT_JOIN,
|
||||
|
||||
;
|
||||
|
||||
private final boolean resetInSubqueryScope;
|
||||
|
||||
248
jOOQ/src/main/java/org/jooq/impl/UDTPathFieldImpl.java
Normal file
248
jOOQ/src/main/java/org/jooq/impl/UDTPathFieldImpl.java
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* https://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: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.lang.Boolean.TRUE;
|
||||
import static org.jooq.impl.SchemaImpl.DEFAULT_SCHEMA;
|
||||
import static org.jooq.impl.Tools.BooleanDataKey.DATA_STORE_ASSIGNMENT;
|
||||
import static org.jooq.tools.StringUtils.defaultIfNull;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.jooq.Binding;
|
||||
import org.jooq.Catalog;
|
||||
import org.jooq.Clause;
|
||||
import org.jooq.Comment;
|
||||
import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Package;
|
||||
import org.jooq.QueryPart;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordQualifier;
|
||||
// ...
|
||||
import org.jooq.Row;
|
||||
import org.jooq.Schema;
|
||||
import org.jooq.Table;
|
||||
// ...
|
||||
import org.jooq.UDT;
|
||||
import org.jooq.UDTPathField;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.impl.QOM.UEmpty;
|
||||
import org.jooq.impl.QOM.UNotYetImplemented;
|
||||
import org.jooq.impl.Tools.BooleanDataKey;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
|
||||
/**
|
||||
* A common base type for UDT path fields.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Internal
|
||||
public /* non-final */ class UDTPathFieldImpl<R extends Record, U extends UDTRecord<U>, T>
|
||||
extends
|
||||
AbstractField<T>
|
||||
implements
|
||||
UDTPathField<R, U, T>,
|
||||
SimpleQueryPart,
|
||||
TypedReference<T>,
|
||||
ScopeMappable,
|
||||
UEmpty
|
||||
{
|
||||
|
||||
private final RecordQualifier<R> qualifier;
|
||||
private final UDT<U> udt;
|
||||
|
||||
UDTPathFieldImpl(Name name, DataType<T> type, RecordQualifier<R> qualifier, UDT<U> udt, Comment comment, Binding<?, T> binding) {
|
||||
super(qualify(qualifier, name), type, comment, binding);
|
||||
|
||||
this.qualifier = qualifier;
|
||||
this.udt = udt;
|
||||
|
||||
qualifier.$name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RecordQualifier<R> getQualifier() {
|
||||
return qualifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final RecordQualifier<U> asQualifier() {
|
||||
return new UDTPathFieldImplAsQualifier();
|
||||
}
|
||||
|
||||
// [#228] TODO Refactor this logic into UDTImpl
|
||||
private class UDTPathFieldImplAsQualifier
|
||||
extends AbstractNamed
|
||||
implements
|
||||
RecordQualifier<U>,
|
||||
FieldsTrait,
|
||||
UNotYetImplemented
|
||||
{
|
||||
UDTPathFieldImplAsQualifier() {
|
||||
super(UDTPathFieldImpl.this.getQualifiedName(), UDTPathFieldImpl.this.getCommentPart());
|
||||
}
|
||||
|
||||
RecordQualifier<R> getQualifier() {
|
||||
return UDTPathFieldImpl.this.getQualifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Catalog getCatalog() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Schema getSchema() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Schema $schema() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Row fieldsRow() {
|
||||
return getUDT().fieldsRow();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Package getPackage() {
|
||||
return getUDT().getPackage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Class<? extends U> getRecordType() {
|
||||
return getUDT().getRecordType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DataType<U> getDataType() {
|
||||
return getUDT().getDataType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final U newRecord() {
|
||||
return getUDT().newRecord();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
UDTPathFieldImpl.this.accept(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UDT<U> getUDT() {
|
||||
return udt;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: QueryPart API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
final boolean parenthesised(Context<?> ctx) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean declaresFields() {
|
||||
return super.declaresFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Clause[] clauses(Context<?> ctx) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
RecordQualifier<R> q = getQualifier();
|
||||
|
||||
// [#228] The disambiguating wrapping in parentheses is only required in references to
|
||||
// a UDT path identifier expression, not in assignments (where it is disallowed)
|
||||
if (!TRUE.equals(ctx.data(DATA_STORE_ASSIGNMENT)) && q instanceof UDTPathFieldImpl.UDTPathFieldImplAsQualifier && ((UDTPathFieldImpl<?, ?, ?>.UDTPathFieldImplAsQualifier) q).getQualifier() instanceof Table)
|
||||
ctx.sql('(').visit(q).sql(").").visit(getUnqualifiedName());
|
||||
else if (q instanceof Table<?> t)
|
||||
TableFieldImpl.accept2(ctx, t, getUnqualifiedName());
|
||||
else
|
||||
ctx.visit(q).sql('.').visit(getUnqualifiedName());
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// XXX: Query Object Model
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX: Object API
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return defaultIfNull(getQualifier().getSchema(), DEFAULT_SCHEMA.get()).getQualifiedName()
|
||||
.append(getQualifier().getUnqualifiedName())
|
||||
.append(getUDT().getUnqualifiedName())
|
||||
.append(getUnqualifiedName()).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object that) {
|
||||
if (this == that)
|
||||
return true;
|
||||
|
||||
// [#2144] UDTPathFieldImpl equality can be decided without executing the
|
||||
// rather expensive implementation of AbstractQueryPart.equals()
|
||||
if (that instanceof UDTPathField<?, ?, ?> other) {
|
||||
return
|
||||
StringUtils.equals(getQualifier(), other.getQualifier()) &&
|
||||
StringUtils.equals(getUDT(), other.getUDT()) &&
|
||||
StringUtils.equals(getName(), other.getName());
|
||||
}
|
||||
|
||||
return super.equals(that);
|
||||
}
|
||||
}
|
||||
76
jOOQ/src/main/java/org/jooq/impl/UDTPathTableFieldImpl.java
Normal file
76
jOOQ/src/main/java/org/jooq/impl/UDTPathTableFieldImpl.java
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* https://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: https://www.jooq.org/legal/licensing
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package org.jooq.impl;
|
||||
|
||||
import org.jooq.Binding;
|
||||
import org.jooq.Comment;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.RecordQualifier;
|
||||
import org.jooq.Table;
|
||||
import org.jooq.UDT;
|
||||
import org.jooq.UDTPathField;
|
||||
import org.jooq.UDTPathTableField;
|
||||
import org.jooq.UDTRecord;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
|
||||
/**
|
||||
* A common base type for table fields that are also {@link UDTPathField}.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@Internal
|
||||
public /* non-final */ class UDTPathTableFieldImpl<R extends Record, U extends UDTRecord<U>, T>
|
||||
extends
|
||||
UDTPathFieldImpl<R, U, T>
|
||||
implements
|
||||
UDTPathTableField<R, U, T>
|
||||
{
|
||||
|
||||
public UDTPathTableFieldImpl(Name name, DataType<T> type, RecordQualifier<R> qualifier, UDT<U> udt, Comment comment, Binding<?, T> binding) {
|
||||
super(name, type, qualifier, udt, comment, binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<R> getTable() {
|
||||
return getQualifier() instanceof Table<R> t ? t : null;
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ public class Reflect {
|
||||
* <pre><code>
|
||||
* Supplier<String> supplier = Reflect.compile("org.joor.Test", """
|
||||
* package org.joor;
|
||||
* @MyAnnotation
|
||||
* @MyAnnotation
|
||||
* class Test implements java.util.function.Supplier<String> {
|
||||
* public String get() {
|
||||
* return "Hello World!";
|
||||
@ -146,7 +146,7 @@ public class Reflect {
|
||||
* <pre><code>
|
||||
* Supplier<String> supplier = Reflect.compile("org.joor.Test", """
|
||||
* package org.joor;
|
||||
* @MyAnnotation
|
||||
* @MyAnnotation
|
||||
* class Test implements java.util.function.Supplier<String> {
|
||||
* public String get() {
|
||||
* return "Hello World!";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user