[jOOQ/jOOQ#13639] Add support for to-many path expressions
- Added code generation support - Added runtime meta data - Mark the feature as experimental - Turn off the feature by default, for as long it's experimental
This commit is contained in:
parent
55a9488101
commit
49b48887c7
@ -70,6 +70,7 @@ abstract class AbstractGenerator implements Generator {
|
||||
boolean generateIndexes = true;
|
||||
boolean generateRelations = true;
|
||||
boolean generateImplicitJoinPathsToOne = true;
|
||||
boolean generateImplicitJoinPathsToMany = true;
|
||||
boolean generateImplicitJoinPathsAsKotlinProperties = true;
|
||||
boolean generateInstanceFields = true;
|
||||
VisibilityModifier generateVisibilityModifier = VisibilityModifier.DEFAULT;
|
||||
@ -300,6 +301,16 @@ abstract class AbstractGenerator implements Generator {
|
||||
this.generateImplicitJoinPathsToOne = generateImplicitJoinPathsToOne;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateImplicitJoinPathsToMany() {
|
||||
return generateImplicitJoinPathsToMany && generateRelations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGenerateImplicitJoinPathsToMany(boolean generateImplicitJoinPathsToMany) {
|
||||
this.generateImplicitJoinPathsToMany = generateImplicitJoinPathsToMany;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean generateImplicitJoinPathsAsKotlinProperties() {
|
||||
return generateImplicitJoinPathsAsKotlinProperties && generateImplicitJoinPathsToOne();
|
||||
|
||||
@ -79,6 +79,7 @@ import org.jooq.meta.EnumDefinition;
|
||||
import org.jooq.meta.ForeignKeyDefinition;
|
||||
import org.jooq.meta.IdentityDefinition;
|
||||
import org.jooq.meta.IndexDefinition;
|
||||
import org.jooq.meta.InverseForeignKeyDefinition;
|
||||
import org.jooq.meta.PackageDefinition;
|
||||
import org.jooq.meta.RoutineDefinition;
|
||||
import org.jooq.meta.SchemaDefinition;
|
||||
@ -284,11 +285,20 @@ public class DefaultGeneratorStrategy extends AbstractGeneratorStrategy {
|
||||
public String getJavaMethodName(Definition definition, Mode mode) {
|
||||
// [#7148] If table A references table B only once, then B is the ideal name
|
||||
// for the implicit JOIN path. Otherwise, fall back to the foreign key name
|
||||
if (getUseTableNameForUnambiguousFKs() && definition instanceof ForeignKeyDefinition fk) {
|
||||
TableDefinition referenced = fk.getReferencedTable();
|
||||
if (getUseTableNameForUnambiguousFKs()) {
|
||||
if (definition instanceof ForeignKeyDefinition fk) {
|
||||
TableDefinition referenced = fk.getReferencedTable();
|
||||
|
||||
if (fk.getKeyTable().getForeignKeys(referenced).size() == 1)
|
||||
return getJavaMethodName(referenced, mode);
|
||||
if (fk.getTable().getForeignKeys(referenced).size() == 1)
|
||||
return getJavaMethodName(referenced, mode);
|
||||
}
|
||||
|
||||
if (definition instanceof InverseForeignKeyDefinition fk) {
|
||||
TableDefinition referencing = fk.getReferencingTable();
|
||||
|
||||
if (fk.getTable().getInverseForeignKeys(referencing).size() == 1)
|
||||
return getJavaMethodName(referencing, mode);
|
||||
}
|
||||
}
|
||||
|
||||
return getJavaClassName0LC(definition, Mode.DEFAULT);
|
||||
|
||||
@ -718,8 +718,10 @@ public class GenerationTool {
|
||||
generator.setGenerateIndexes(g.getGenerate().isIndexes());
|
||||
if (g.getGenerate().isRelations() != null)
|
||||
generator.setGenerateRelations(g.getGenerate().isRelations());
|
||||
if (g.getGenerate().isImplicitJoinPathsToOne() != null)
|
||||
if (g.getGenerate().isImplicitJoinPathsToMany() != null)
|
||||
generator.setGenerateImplicitJoinPathsToOne(g.getGenerate().isImplicitJoinPathsToOne());
|
||||
if (g.getGenerate().isImplicitJoinPathsToOne() != null)
|
||||
generator.setGenerateImplicitJoinPathsToMany(g.getGenerate().isImplicitJoinPathsToMany());
|
||||
if (g.getGenerate().isImplicitJoinPathsAsKotlinProperties() != null)
|
||||
generator.setGenerateImplicitJoinPathsAsKotlinProperties(g.getGenerate().isImplicitJoinPathsAsKotlinProperties());
|
||||
if (g.getGenerate().isDeprecated() != null)
|
||||
|
||||
@ -131,6 +131,18 @@ public interface Generator {
|
||||
*/
|
||||
void setGenerateImplicitJoinPathsToOne(boolean generateImplicitJoinPathsToOne);
|
||||
|
||||
/**
|
||||
* Whether implicit join path constructors on generated tables for incoming
|
||||
* foreign key relationships (to-many relationships) should be generated.
|
||||
*/
|
||||
boolean generateImplicitJoinPathsToMany();
|
||||
|
||||
/**
|
||||
* Whether implicit join path constructors on generated tables for incoming
|
||||
* foreign key relationships (to-many relationships) should be generated.
|
||||
*/
|
||||
void setGenerateImplicitJoinPathsToMany(boolean generateImplicitJoinPathsToMany);
|
||||
|
||||
/**
|
||||
* Whether implicit join path constructors should be offered as properties
|
||||
* in Kotlin.
|
||||
|
||||
@ -108,6 +108,7 @@ import org.jooq.ForeignKey;
|
||||
import org.jooq.Generated;
|
||||
import org.jooq.Identity;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.InverseForeignKey;
|
||||
// ...
|
||||
import org.jooq.Name;
|
||||
import org.jooq.OrderField;
|
||||
@ -177,6 +178,7 @@ import org.jooq.meta.ForeignKeyDefinition;
|
||||
import org.jooq.meta.IdentityDefinition;
|
||||
import org.jooq.meta.IndexColumnDefinition;
|
||||
import org.jooq.meta.IndexDefinition;
|
||||
import org.jooq.meta.InverseForeignKeyDefinition;
|
||||
import org.jooq.meta.JavaTypeResolver;
|
||||
import org.jooq.meta.PackageDefinition;
|
||||
import org.jooq.meta.ParameterDefinition;
|
||||
@ -6352,21 +6354,41 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.println("}");
|
||||
}
|
||||
|
||||
if (generateImplicitJoinPathsToOne() && generateGlobalKeyReferences() && !table.isTableValuedFunction()) {
|
||||
out.println();
|
||||
if (generateGlobalKeyReferences() && !table.isTableValuedFunction()) {
|
||||
if (generateImplicitJoinPathsToOne()) {
|
||||
out.println();
|
||||
|
||||
if (scala) {
|
||||
out.println("%sdef this(child: %s[_ <: %s], key: %s[_ <: %s, %s]) = this(%s.createPathAlias(child, key), child, key, %s, null)",
|
||||
visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId);
|
||||
if (scala) {
|
||||
out.println("%sdef this(child: %s[_ <: %s], key: %s[_ <: %s, %s]) = this(%s.createPathAlias(child, key), child, key, %s, null)",
|
||||
visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId);
|
||||
}
|
||||
else if (kotlin) {
|
||||
out.println("%sconstructor(child: %s<out %s>, key: %s<out %s, %s>): this(%s.createPathAlias(child, key), child, key, %s, null)",
|
||||
visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId);
|
||||
}
|
||||
else {
|
||||
out.println("%s<O extends %s> %s(%s<O> child, %s<O, %s> key) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType);
|
||||
out.println("super(child, key, %s);", tableId);
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
else if (kotlin) {
|
||||
out.println("%sconstructor(child: %s<out %s>, key: %s<out %s, %s>): this(%s.createPathAlias(child, key), child, key, %s, null)",
|
||||
visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId);
|
||||
}
|
||||
else {
|
||||
out.println("%s<O extends %s> %s(%s<O> child, %s<O, %s> key) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType);
|
||||
out.println("super(child, key, %s);", tableId);
|
||||
out.println("}");
|
||||
|
||||
if (generateImplicitJoinPathsToMany()) {
|
||||
out.println();
|
||||
|
||||
if (scala) {
|
||||
out.println("%sdef this(parent: %s[_ <: %s], key: %s[_ <: %s, %s]) = this(%s.createPathAlias(parent, key), parent, key, %s, null)",
|
||||
visibility(), Table.class, Record.class, InverseForeignKey.class, Record.class, recordType, Internal.class, tableId);
|
||||
}
|
||||
else if (kotlin) {
|
||||
out.println("%sconstructor(parent: %s<out %s>, key: %s<out %s, %s>): this(%s.createPathAlias(parent, key), parent, key, %s, null)",
|
||||
visibility(), Table.class, Record.class, InverseForeignKey.class, Record.class, recordType, Internal.class, tableId);
|
||||
}
|
||||
else {
|
||||
out.println("%s<O extends %s> %s(%s<O> parent, %s<O, %s> key) {", visibility(), Record.class, className, Table.class, InverseForeignKey.class, recordType);
|
||||
out.println("super(parent, key, %s);", tableId);
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6597,13 +6619,13 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
|
||||
// Foreign keys
|
||||
List<ForeignKeyDefinition> foreignKeys = table.getForeignKeys();
|
||||
List<ForeignKeyDefinition> outboundFKs = table.getForeignKeys();
|
||||
|
||||
// [#7554] [#8028] Not yet supported with global key references turned off
|
||||
if (foreignKeys.size() > 0 && generateGlobalKeyReferences()) {
|
||||
if (outboundFKs.size() > 0 && generateGlobalKeyReferences()) {
|
||||
final List<String> keyFullIds = kotlin
|
||||
? out.ref(getStrategy().getFullJavaIdentifiers(foreignKeys))
|
||||
: out.ref(getStrategy().getFullJavaIdentifiers(foreignKeys), 2);
|
||||
? out.ref(getStrategy().getFullJavaIdentifiers(outboundFKs))
|
||||
: out.ref(getStrategy().getFullJavaIdentifiers(outboundFKs), 2);
|
||||
|
||||
if (scala) {
|
||||
out.println();
|
||||
@ -6629,7 +6651,7 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
out.println();
|
||||
|
||||
// [#8762] Cache these calls for much improved runtime performance!
|
||||
for (ForeignKeyDefinition foreignKey : foreignKeys) {
|
||||
for (ForeignKeyDefinition foreignKey : outboundFKs) {
|
||||
final String referencedTableClassName = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencedTable()));
|
||||
final String keyMethodName = out.ref(getStrategy().getJavaMethodName(foreignKey));
|
||||
|
||||
@ -6643,8 +6665,8 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
Map<TableDefinition, Long> pathCounts = foreignKeys.stream().collect(groupingBy(ForeignKeyDefinition::getReferencedTable, counting()));
|
||||
for (ForeignKeyDefinition foreignKey : foreignKeys) {
|
||||
Map<TableDefinition, Long> pathCounts = outboundFKs.stream().collect(groupingBy(ForeignKeyDefinition::getReferencedTable, counting()));
|
||||
for (ForeignKeyDefinition foreignKey : outboundFKs) {
|
||||
final String keyFullId = kotlin
|
||||
? out.ref(getStrategy().getFullJavaIdentifier(foreignKey))
|
||||
: out.ref(getStrategy().getFullJavaIdentifier(foreignKey), 2);
|
||||
@ -6686,6 +6708,74 @@ public class JavaGenerator extends AbstractGenerator {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<InverseForeignKeyDefinition> inboundFKs = table.getInverseForeignKeys();
|
||||
if (inboundFKs.size() > 0 && generateGlobalKeyReferences()) {
|
||||
|
||||
// Inbound (to-many) implicit join paths
|
||||
if (generateImplicitJoinPathsToMany()) {
|
||||
if (scala) {}
|
||||
else {
|
||||
out.println();
|
||||
|
||||
// [#8762] Cache these calls for much improved runtime performance!
|
||||
for (InverseForeignKeyDefinition foreignKey : inboundFKs) {
|
||||
final String referencingTableClassName = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencingTable()));
|
||||
final String keyMethodName = out.ref(getStrategy().getJavaMethodName(foreignKey));
|
||||
|
||||
// [#13008] Prevent conflicts with the below leading underscore
|
||||
final String unquotedKeyMethodName = keyMethodName.replace("`", "");
|
||||
|
||||
if (kotlin)
|
||||
out.println("private lateinit var _%s: %s", unquotedKeyMethodName, referencingTableClassName);
|
||||
else
|
||||
out.println("private transient %s _%s;", referencingTableClassName, keyMethodName);
|
||||
}
|
||||
}
|
||||
|
||||
Map<TableDefinition, Long> pathCounts = inboundFKs.stream().collect(groupingBy(InverseForeignKeyDefinition::getReferencingTable, counting()));
|
||||
for (InverseForeignKeyDefinition foreignKey : inboundFKs) {
|
||||
final String keyFullId = kotlin
|
||||
? out.ref(getStrategy().getFullJavaIdentifier(foreignKey))
|
||||
: out.ref(getStrategy().getFullJavaIdentifier(foreignKey), 2);
|
||||
final String referencingTableClassName = out.ref(getStrategy().getFullJavaClassName(foreignKey.getReferencingTable()));
|
||||
final String keyMethodName = out.ref(getStrategy().getJavaMethodName(foreignKey));
|
||||
final String unquotedKeyMethodName = keyMethodName.replace("`", "");
|
||||
|
||||
out.javadoc(
|
||||
"Get the implicit to-many join path to the <code>" + foreignKey.getReferencingTable().getQualifiedName() + "</code> table"
|
||||
+ (pathCounts.get(foreignKey.getReferencingTable()) > 1 ? ", via the <code>" + foreignKey.getInputName() + "</code> key" : "")
|
||||
+ ".<p><strong>EXPERIMENTAL! DO NOT USE THIS FEATURE YET.</strong>"
|
||||
);
|
||||
|
||||
if (scala) {
|
||||
out.println("%slazy val %s: %s = { new %s(this, %s.getInverseKey()) }", visibility(), scalaWhitespaceSuffix(keyMethodName), referencingTableClassName, referencingTableClassName, keyFullId);
|
||||
}
|
||||
else if (kotlin) {
|
||||
out.println("%sfun %s(): %s {", visibility(), keyMethodName, referencingTableClassName);
|
||||
out.println("if (!this::_%s.isInitialized)", unquotedKeyMethodName);
|
||||
out.println("_%s = %s(this, %s.inverseKey)", unquotedKeyMethodName, referencingTableClassName, keyFullId);
|
||||
out.println();
|
||||
out.println("return _%s;", unquotedKeyMethodName);
|
||||
out.println("}");
|
||||
|
||||
if (generateImplicitJoinPathsAsKotlinProperties()) {
|
||||
out.println();
|
||||
out.println("%sval %s: %s", visibility(), keyMethodName, referencingTableClassName);
|
||||
out.tab(1).println("get(): %s = %s()", referencingTableClassName, keyMethodName);
|
||||
}
|
||||
}
|
||||
else {
|
||||
out.println("%s%s %s() {", visibility(), referencingTableClassName, keyMethodName);
|
||||
out.println("if (_%s == null)", keyMethodName);
|
||||
out.println("_%s = new %s(this, %s.getInverseKey());", keyMethodName, referencingTableClassName, keyFullId);
|
||||
out.println();
|
||||
out.println("return _%s;", keyMethodName);
|
||||
out.println("}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<CheckConstraintDefinition> cc = table.getCheckConstraints();
|
||||
|
||||
@ -160,6 +160,28 @@ implements
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<InverseForeignKeyDefinition> getInverseForeignKeys() {
|
||||
List<InverseForeignKeyDefinition> result = new ArrayList<>();
|
||||
|
||||
for (UniqueKeyDefinition uk : getKeys())
|
||||
for (ForeignKeyDefinition fk : uk.getForeignKeys())
|
||||
result.add(fk.inverse());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<InverseForeignKeyDefinition> getInverseForeignKeys(TableDefinition referencing) {
|
||||
List<InverseForeignKeyDefinition> result = new ArrayList<>();
|
||||
|
||||
for (InverseForeignKeyDefinition key : getInverseForeignKeys())
|
||||
if (referencing.equals(key.getReferencingTable()))
|
||||
result.add(key);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<CheckConstraintDefinition> getCheckConstraints() {
|
||||
return getDatabase().getRelations().getCheckConstraints(this);
|
||||
|
||||
@ -100,4 +100,9 @@ public class DefaultForeignKeyDefinition extends AbstractConstraintDefinition im
|
||||
|
||||
return keys.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InverseForeignKeyDefinition inverse() {
|
||||
return new DefaultInverseForeignKeyDefinition(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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.meta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.Name;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public class DefaultInverseForeignKeyDefinition extends AbstractDefinition implements InverseForeignKeyDefinition {
|
||||
|
||||
private final ForeignKeyDefinition foreignKey;
|
||||
|
||||
public DefaultInverseForeignKeyDefinition(ForeignKeyDefinition foreignKey) {
|
||||
super(foreignKey.getDatabase(), foreignKey.getSchema(), foreignKey.getName());
|
||||
|
||||
this.foreignKey = foreignKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDefinition getTable() {
|
||||
return foreignKey.getReferencedTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enforced() {
|
||||
return foreignKey.enforced();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ColumnDefinition> getKeyColumns() {
|
||||
return foreignKey.getReferencedColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TableDefinition getReferencingTable() {
|
||||
return foreignKey.getTable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ColumnDefinition> getReferencingColumns() {
|
||||
return foreignKey.getKeyColumns();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForeignKeyDefinition foreignKey() {
|
||||
return foreignKey;
|
||||
}
|
||||
}
|
||||
@ -88,4 +88,9 @@ public interface ForeignKeyDefinition extends ConstraintDefinition {
|
||||
* Count the number of references between referencing and referenced tables.
|
||||
*/
|
||||
int countSimilarReferences();
|
||||
|
||||
/**
|
||||
* Get the inverse key.
|
||||
*/
|
||||
InverseForeignKeyDefinition inverse();
|
||||
}
|
||||
|
||||
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.meta;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An object holding information about an inverse foreign key relationship.
|
||||
*
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface InverseForeignKeyDefinition extends ConstraintDefinition {
|
||||
|
||||
/**
|
||||
* The list of columns making up the unique key.
|
||||
*/
|
||||
List<ColumnDefinition> getKeyColumns();
|
||||
|
||||
/**
|
||||
* The definition of the referencing table.
|
||||
*/
|
||||
TableDefinition getReferencingTable();
|
||||
|
||||
/**
|
||||
* The list of columns referencing this unique key from the foreign key.
|
||||
*/
|
||||
List<ColumnDefinition> getReferencingColumns();
|
||||
|
||||
/**
|
||||
* Get the foreign key this is an inverse of.
|
||||
*/
|
||||
ForeignKeyDefinition foreignKey();
|
||||
}
|
||||
@ -128,6 +128,16 @@ public interface TableDefinition extends Definition {
|
||||
*/
|
||||
List<ForeignKeyDefinition> getForeignKeys(TableDefinition referenced);
|
||||
|
||||
/**
|
||||
* Get the inverse foreign keys for this table.
|
||||
*/
|
||||
List<InverseForeignKeyDefinition> getInverseForeignKeys();
|
||||
|
||||
/**
|
||||
* Get the inverse foreign keys for this table referenced from a specific table.
|
||||
*/
|
||||
List<InverseForeignKeyDefinition> getInverseForeignKeys(TableDefinition referencing);
|
||||
|
||||
/**
|
||||
* Get the <code>CHECK</code> constraints for this table.
|
||||
*/
|
||||
|
||||
@ -38,6 +38,8 @@ public class Generate implements Serializable, XMLAppendable
|
||||
protected Boolean sequenceFlags = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean implicitJoinPathsToOne = true;
|
||||
@XmlElement(defaultValue = "false")
|
||||
protected Boolean implicitJoinPathsToMany = false;
|
||||
@XmlElement(defaultValue = "true")
|
||||
protected Boolean implicitJoinPathsUseTableNameForUnambiguousFKs = true;
|
||||
@XmlElement(defaultValue = "true")
|
||||
@ -336,6 +338,30 @@ public class Generate implements Serializable, XMLAppendable
|
||||
this.implicitJoinPathsToOne = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate implicit join path constructors on generated tables for incoming foreign key relationships (to-many relationships)<p><strong>EXPERIMENTAL functionality! Do not use this feature, yet</strong>
|
||||
*
|
||||
* @return
|
||||
* possible object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public Boolean isImplicitJoinPathsToMany() {
|
||||
return implicitJoinPathsToMany;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the implicitJoinPathsToMany property.
|
||||
*
|
||||
* @param value
|
||||
* allowed object is
|
||||
* {@link Boolean }
|
||||
*
|
||||
*/
|
||||
public void setImplicitJoinPathsToMany(Boolean value) {
|
||||
this.implicitJoinPathsToMany = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether names of unambiguous {@link org.jooq.meta.ForeignKeyDefinition} should be based
|
||||
* on the referenced {@link org.jooq.meta.TableDefinition}.
|
||||
@ -2637,6 +2663,11 @@ public class Generate implements Serializable, XMLAppendable
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withImplicitJoinPathsToMany(Boolean value) {
|
||||
setImplicitJoinPathsToMany(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Generate withImplicitJoinPathsUseTableNameForUnambiguousFKs(Boolean value) {
|
||||
setImplicitJoinPathsUseTableNameForUnambiguousFKs(value);
|
||||
return this;
|
||||
@ -3181,6 +3212,7 @@ public class Generate implements Serializable, XMLAppendable
|
||||
builder.append("relations", relations);
|
||||
builder.append("sequenceFlags", sequenceFlags);
|
||||
builder.append("implicitJoinPathsToOne", implicitJoinPathsToOne);
|
||||
builder.append("implicitJoinPathsToMany", implicitJoinPathsToMany);
|
||||
builder.append("implicitJoinPathsUseTableNameForUnambiguousFKs", implicitJoinPathsUseTableNameForUnambiguousFKs);
|
||||
builder.append("implicitJoinPathsAsKotlinProperties", implicitJoinPathsAsKotlinProperties);
|
||||
builder.append("deprecated", deprecated);
|
||||
@ -3335,6 +3367,15 @@ public class Generate implements Serializable, XMLAppendable
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (implicitJoinPathsToMany == null) {
|
||||
if (other.implicitJoinPathsToMany!= null) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!implicitJoinPathsToMany.equals(other.implicitJoinPathsToMany)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (implicitJoinPathsUseTableNameForUnambiguousFKs == null) {
|
||||
if (other.implicitJoinPathsUseTableNameForUnambiguousFKs!= null) {
|
||||
return false;
|
||||
@ -4219,6 +4260,7 @@ public class Generate implements Serializable, XMLAppendable
|
||||
result = ((prime*result)+((relations == null)? 0 :relations.hashCode()));
|
||||
result = ((prime*result)+((sequenceFlags == null)? 0 :sequenceFlags.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathsToOne == null)? 0 :implicitJoinPathsToOne.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathsToMany == null)? 0 :implicitJoinPathsToMany.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathsUseTableNameForUnambiguousFKs == null)? 0 :implicitJoinPathsUseTableNameForUnambiguousFKs.hashCode()));
|
||||
result = ((prime*result)+((implicitJoinPathsAsKotlinProperties == null)? 0 :implicitJoinPathsAsKotlinProperties.hashCode()));
|
||||
result = ((prime*result)+((deprecated == null)? 0 :deprecated.hashCode()));
|
||||
|
||||
@ -1951,6 +1951,10 @@ This is a prerequisite for various advanced features]]></jxb:javadoc></jxb:prope
|
||||
<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>
|
||||
</element>
|
||||
|
||||
<element name="implicitJoinPathsToMany" type="boolean" default="false" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Generate implicit join path constructors on generated tables for incoming foreign key relationships (to-many relationships)<p><strong>EXPERIMENTAL functionality! Do not use this feature, yet</strong>]]></jxb:javadoc></jxb:property></appinfo></annotation>
|
||||
</element>
|
||||
|
||||
<element name="implicitJoinPathsUseTableNameForUnambiguousFKs" type="boolean" default="true" minOccurs="0" maxOccurs="1">
|
||||
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether names of unambiguous {@link org.jooq.meta.ForeignKeyDefinition} should be based
|
||||
|
||||
@ -53,18 +53,24 @@ import org.jetbrains.annotations.Nullable;
|
||||
* Instances of this type cannot be created directly. They are available from
|
||||
* generated code.
|
||||
*
|
||||
* @param <R> The <code>FOREIGN KEY</code>'s owner table record
|
||||
* @param <O> The referenced <code>KEY</code>'s owner table record
|
||||
* @param <CHILD> The <code>FOREIGN KEY</code>'s owner table record
|
||||
* @param <PARENT> The referenced <code>KEY</code>'s owner table record
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
public interface ForeignKey<CHILD extends Record, PARENT extends Record> extends Key<CHILD> {
|
||||
|
||||
/**
|
||||
* The inverse key.
|
||||
*/
|
||||
@NotNull
|
||||
InverseForeignKey<PARENT, CHILD> getInverseKey();
|
||||
|
||||
/**
|
||||
* The referenced <code>UniqueKey</code>.
|
||||
*/
|
||||
@NotNull
|
||||
UniqueKey<O> getKey();
|
||||
UniqueKey<PARENT> getKey();
|
||||
|
||||
/**
|
||||
* The fields that make up the referenced <code>UniqueKey</code>.
|
||||
@ -74,7 +80,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
* {@link UniqueKey#getFields()}, but not necessarily so.
|
||||
*/
|
||||
@NotNull
|
||||
List<TableField<O, ?>> getKeyFields();
|
||||
List<TableField<PARENT, ?>> getKeyFields();
|
||||
|
||||
/**
|
||||
* The fields that make up the referenced <code>UniqueKey</code>.
|
||||
@ -86,7 +92,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
* @see #getKeyFields()
|
||||
*/
|
||||
@NotNull
|
||||
TableField<O, ?> @NotNull [] getKeyFieldsArray();
|
||||
TableField<PARENT, ?> @NotNull [] getKeyFieldsArray();
|
||||
|
||||
/**
|
||||
* Fetch a parent record of a given record through this foreign key
|
||||
@ -100,7 +106,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
*/
|
||||
@Nullable
|
||||
@Blocking
|
||||
O fetchParent(R record) throws DataAccessException;
|
||||
PARENT fetchParent(CHILD record) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Fetch parent records of a given set of record through this foreign key
|
||||
@ -114,7 +120,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
*/
|
||||
@NotNull
|
||||
@Blocking
|
||||
Result<O> fetchParents(R... records) throws DataAccessException;
|
||||
Result<PARENT> fetchParents(CHILD... records) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Fetch parent records of a given set of record through this foreign key
|
||||
@ -128,7 +134,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
*/
|
||||
@NotNull
|
||||
@Blocking
|
||||
Result<O> fetchParents(Collection<? extends R> records) throws DataAccessException;
|
||||
Result<PARENT> fetchParents(Collection<? extends CHILD> records) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Fetch child records of a given record through this foreign key
|
||||
@ -142,7 +148,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
*/
|
||||
@NotNull
|
||||
@Blocking
|
||||
Result<R> fetchChildren(O record) throws DataAccessException;
|
||||
Result<CHILD> fetchChildren(PARENT record) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Fetch child records of a given set of records through this foreign key
|
||||
@ -157,7 +163,7 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
*/
|
||||
@NotNull
|
||||
@Blocking
|
||||
Result<R> fetchChildren(O... records) throws DataAccessException;
|
||||
Result<CHILD> fetchChildren(PARENT... records) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Fetch child records of a given set of records through this foreign key
|
||||
@ -172,47 +178,47 @@ public interface ForeignKey<R extends Record, O extends Record> extends Key<R> {
|
||||
*/
|
||||
@NotNull
|
||||
@Blocking
|
||||
Result<R> fetchChildren(Collection<? extends O> records) throws DataAccessException;
|
||||
Result<CHILD> fetchChildren(Collection<? extends PARENT> records) throws DataAccessException;
|
||||
|
||||
/**
|
||||
* Get a table expression representing the parent of a record, given this
|
||||
* foreign key.
|
||||
*/
|
||||
@NotNull
|
||||
Table<O> parent(R record);
|
||||
Table<PARENT> parent(CHILD record);
|
||||
|
||||
/**
|
||||
* Get a table expression representing the parents of a record, given this
|
||||
* foreign key.
|
||||
*/
|
||||
@NotNull
|
||||
Table<O> parents(R... records);
|
||||
Table<PARENT> parents(CHILD... records);
|
||||
|
||||
/**
|
||||
* Get a table expression representing the parents of a record, given this
|
||||
* foreign key.
|
||||
*/
|
||||
@NotNull
|
||||
Table<O> parents(Collection<? extends R> records);
|
||||
Table<PARENT> parents(Collection<? extends CHILD> records);
|
||||
|
||||
/**
|
||||
* Get a table expression representing the children of a record, given this
|
||||
* foreign key.
|
||||
*/
|
||||
@NotNull
|
||||
Table<R> children(O record);
|
||||
Table<CHILD> children(PARENT record);
|
||||
|
||||
/**
|
||||
* Get a table expression representing the children of a record, given this
|
||||
* foreign key.
|
||||
*/
|
||||
@NotNull
|
||||
Table<R> children(O... records);
|
||||
Table<CHILD> children(PARENT... records);
|
||||
|
||||
/**
|
||||
* Get a table expression representing the children of a record, given this
|
||||
* foreign key.
|
||||
*/
|
||||
@NotNull
|
||||
Table<R> children(Collection<? extends O> records);
|
||||
Table<CHILD> children(Collection<? extends PARENT> records);
|
||||
}
|
||||
|
||||
90
jOOQ/src/main/java/org/jooq/InverseForeignKey.java
Normal file
90
jOOQ/src/main/java/org/jooq/InverseForeignKey.java
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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 java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.exception.DataAccessException;
|
||||
|
||||
import org.jetbrains.annotations.Blocking;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* An <code>InverseForeignKey</code> is an inverse {@link ForeignKey}. It
|
||||
* represents an inverse <code>FOREIGN KEY</code> relationship between two
|
||||
* tables.
|
||||
* <p>
|
||||
* Instances of this type cannot be created directly. They are available from
|
||||
* generated code.
|
||||
*
|
||||
* @param <PARENT> The referenced <code>KEY</code>'s owner table record
|
||||
* @param <CHILD> The <code>FOREIGN KEY</code>'s owner table record
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
public interface InverseForeignKey<PARENT extends Record, CHILD extends Record> extends Key<PARENT> {
|
||||
|
||||
/**
|
||||
* The referenced <code>UniqueKey</code>.
|
||||
*/
|
||||
@NotNull
|
||||
ForeignKey<CHILD, PARENT> getForeignKey();
|
||||
|
||||
/**
|
||||
* The fields that make up the referenced <code>UniqueKey</code>.
|
||||
* <p>
|
||||
* This returns the order in which the fields of {@link #getKey()} are
|
||||
* referenced, which is usually the same as the fields of
|
||||
* {@link UniqueKey#getFields()}, but not necessarily so.
|
||||
*/
|
||||
@NotNull
|
||||
List<TableField<CHILD, ?>> getForeignKeyFields();
|
||||
|
||||
/**
|
||||
* The fields that make up the referenced <code>UniqueKey</code>.
|
||||
* <p>
|
||||
* This returns the order in which the fields of {@link #getKey()} are
|
||||
* referenced, which is usually the same as the fields of
|
||||
* {@link UniqueKey#getFieldsArray()}, but not necessarily so.
|
||||
*
|
||||
* @see #getKeyFields()
|
||||
*/
|
||||
@NotNull
|
||||
TableField<CHILD, ?> @NotNull [] getForeignKeyFieldsArray();
|
||||
}
|
||||
@ -62,6 +62,7 @@ import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.Identity;
|
||||
import org.jooq.Index;
|
||||
import org.jooq.InverseForeignKey;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.OrderField;
|
||||
import org.jooq.ParamMode;
|
||||
@ -306,6 +307,25 @@ public final class Internal {
|
||||
return DSL.name("alias_" + hash(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for path aliases.
|
||||
*/
|
||||
@NotNull
|
||||
public static final Name createPathAlias(Table<?> parent, InverseForeignKey<?, ?> path) {
|
||||
Name name = DSL.name(path.getName());
|
||||
|
||||
if (parent instanceof TableImpl<?> t) {
|
||||
Table<?> ancestor = t.parent;
|
||||
|
||||
if (ancestor != null)
|
||||
name = createPathAlias(ancestor, t.parentPath).append(name);
|
||||
else
|
||||
name = parent.getQualifiedName().append(name);
|
||||
}
|
||||
|
||||
return DSL.name("alias_" + hash(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method for parameters.
|
||||
*/
|
||||
|
||||
@ -1733,7 +1733,7 @@ final class Interpreter {
|
||||
|
||||
private final class InterpretedTable extends TableImpl<Record> {
|
||||
InterpretedTable(MutableSchema.InterpretedSchema schema) {
|
||||
super(MutableTable.this.name(), schema, null, null, null, null, MutableTable.this.comment(), MutableTable.this.options);
|
||||
super(MutableTable.this.name(), schema, null, (ForeignKey<?, Record>) null, null, null, MutableTable.this.comment(), MutableTable.this.options);
|
||||
|
||||
for (MutableField field : MutableTable.this.fields)
|
||||
createField(field.name(), field.type, field.comment() != null ? field.comment().getComment() : null);
|
||||
|
||||
89
jOOQ/src/main/java/org/jooq/impl/InverseReferenceImpl.java
Normal file
89
jOOQ/src/main/java/org/jooq/impl/InverseReferenceImpl.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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 java.util.List;
|
||||
|
||||
import org.jooq.ConstraintEnforcementStep;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.InverseForeignKey;
|
||||
import org.jooq.TableField;
|
||||
import org.jooq.impl.QOM.UTransient;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
class InverseReferenceImpl<R extends Record, O extends Record>
|
||||
extends
|
||||
AbstractKey<R>
|
||||
implements
|
||||
InverseForeignKey<R, O>,
|
||||
UTransient
|
||||
{
|
||||
|
||||
private final ForeignKey<O, R> foreignKey;
|
||||
|
||||
InverseReferenceImpl(ForeignKey<O, R> foreignKey) {
|
||||
super(foreignKey.getKey().getTable(), foreignKey.getQualifiedName(), foreignKey.getKeyFieldsArray(), foreignKey.enforced());
|
||||
|
||||
this.foreignKey = foreignKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final ForeignKey<O, R> getForeignKey() {
|
||||
return foreignKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<TableField<O, ?>> getForeignKeyFields() {
|
||||
return foreignKey.getFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TableField<O, ?>[] getForeignKeyFieldsArray() {
|
||||
return foreignKey.getFieldsArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
ConstraintEnforcementStep constraint0() {
|
||||
return ((ReferenceImpl<O, R>) foreignKey).constraint0();
|
||||
}
|
||||
}
|
||||
@ -733,7 +733,7 @@ final class MetaImpl extends AbstractMeta {
|
||||
private final Result<Record> uks;
|
||||
|
||||
MetaTable(String name, MetaSchema schema, Result<Record> columns, Result<Record> uks, String remarks, TableType tableType) {
|
||||
super(name(name), schema, null, null, null, null, comment(remarks), tableOption(dsl(), schema, name, tableType));
|
||||
super(name(name), schema, null, (ForeignKey<?, Record>) null, null, null, comment(remarks), tableOption(dsl(), schema, name, tableType));
|
||||
|
||||
// Possible scenarios for columns being null:
|
||||
// - The "table" is in fact a SYNONYM
|
||||
|
||||
@ -51,6 +51,7 @@ import org.jooq.ConstraintEnforcementStep;
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.InverseForeignKey;
|
||||
import org.jooq.Name;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
@ -64,12 +65,18 @@ import org.jooq.impl.QOM.UEmpty;
|
||||
/**
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class ReferenceImpl<R extends Record, O extends Record> extends AbstractKey<R> implements ForeignKey<R, O>, UEmpty {
|
||||
final class ReferenceImpl<CHILD extends Record, PARENT extends Record>
|
||||
extends
|
||||
AbstractKey<CHILD>
|
||||
implements
|
||||
ForeignKey<CHILD, PARENT>,
|
||||
UEmpty
|
||||
{
|
||||
|
||||
private final UniqueKey<O> uk;
|
||||
private final TableField<O, ?>[] ukFields;
|
||||
private final UniqueKey<PARENT> uk;
|
||||
private final TableField<PARENT, ?>[] ukFields;
|
||||
|
||||
ReferenceImpl(Table<R> table, Name name, TableField<R, ?>[] fkFields, UniqueKey<O> uk, TableField<O, ?>[] ukFields, boolean enforced) {
|
||||
ReferenceImpl(Table<CHILD> table, Name name, TableField<CHILD, ?>[] fkFields, UniqueKey<PARENT> uk, TableField<PARENT, ?>[] ukFields, boolean enforced) {
|
||||
super(table, name, fkFields, enforced);
|
||||
|
||||
this.uk = uk;
|
||||
@ -77,33 +84,38 @@ final class ReferenceImpl<R extends Record, O extends Record> extends AbstractKe
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UniqueKey<O> getKey() {
|
||||
public final InverseForeignKey<PARENT, CHILD> getInverseKey() {
|
||||
return new InverseReferenceImpl<>(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final UniqueKey<PARENT> getKey() {
|
||||
return uk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<TableField<O, ?>> getKeyFields() {
|
||||
public final List<TableField<PARENT, ?>> getKeyFields() {
|
||||
return Arrays.asList(ukFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final TableField<O, ?>[] getKeyFieldsArray() {
|
||||
public final TableField<PARENT, ?>[] getKeyFieldsArray() {
|
||||
return ukFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final O fetchParent(R record) {
|
||||
public final PARENT fetchParent(CHILD record) {
|
||||
return filterOne(fetchParents(record));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SafeVarargs
|
||||
public final Result<O> fetchParents(R... records) {
|
||||
public final Result<PARENT> fetchParents(CHILD... records) {
|
||||
return fetchParents(list(records));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Result<O> fetchParents(Collection<? extends R> records) {
|
||||
public final Result<PARENT> fetchParents(Collection<? extends CHILD> records) {
|
||||
if (records == null || records.size() == 0)
|
||||
return new ResultImpl<>(new DefaultConfiguration(), uk.getFields());
|
||||
else
|
||||
@ -111,18 +123,18 @@ final class ReferenceImpl<R extends Record, O extends Record> extends AbstractKe
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Result<R> fetchChildren(O record) {
|
||||
public final Result<CHILD> fetchChildren(PARENT record) {
|
||||
return fetchChildren(list(record));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SafeVarargs
|
||||
public final Result<R> fetchChildren(O... records) {
|
||||
public final Result<CHILD> fetchChildren(PARENT... records) {
|
||||
return fetchChildren(list(records));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Result<R> fetchChildren(Collection<? extends O> records) {
|
||||
public final Result<CHILD> fetchChildren(Collection<? extends PARENT> records) {
|
||||
if (records == null || records.size() == 0)
|
||||
return new ResultImpl<>(new DefaultConfiguration(), getFields());
|
||||
else
|
||||
@ -130,34 +142,34 @@ final class ReferenceImpl<R extends Record, O extends Record> extends AbstractKe
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<O> parent(R record) {
|
||||
public final Table<PARENT> parent(CHILD record) {
|
||||
return parents(list(record));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@Override
|
||||
public final Table<O> parents(R... records) {
|
||||
public final Table<PARENT> parents(CHILD... records) {
|
||||
return parents(list(records));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<O> parents(Collection<? extends R> records) {
|
||||
public final Table<PARENT> parents(Collection<? extends CHILD> records) {
|
||||
return table(records, uk.getTable(), uk.getFieldsArray(), getFieldsArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<R> children(O record) {
|
||||
public final Table<CHILD> children(PARENT record) {
|
||||
return children(list(record));
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
@Override
|
||||
public final Table<R> children(O... records) {
|
||||
public final Table<CHILD> children(PARENT... records) {
|
||||
return children(list(records));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final Table<R> children(Collection<? extends O> records) {
|
||||
public final Table<CHILD> children(Collection<? extends PARENT> records) {
|
||||
return table(records, getTable(), getFieldsArray(), uk.getFieldsArray());
|
||||
}
|
||||
|
||||
|
||||
@ -71,6 +71,7 @@ import org.jooq.Context;
|
||||
import org.jooq.DataType;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.ForeignKey;
|
||||
import org.jooq.InverseForeignKey;
|
||||
import org.jooq.JoinType;
|
||||
import org.jooq.Name;
|
||||
// ...
|
||||
@ -124,6 +125,8 @@ implements
|
||||
protected final Field<?>[] parameters;
|
||||
final Table<?> child;
|
||||
final ForeignKey<?, R> childPath;
|
||||
final Table<?> parent;
|
||||
final InverseForeignKey<?, R> parentPath;
|
||||
|
||||
/**
|
||||
* @deprecated - 3.10 - [#5996] - Use {@link #TableImpl(Name)} instead (or
|
||||
@ -171,19 +174,19 @@ implements
|
||||
}
|
||||
|
||||
public TableImpl(Name name) {
|
||||
this(name, null, null, null, null, null, (Comment) null);
|
||||
this(name, null, null, (ForeignKey<?, R>) null, null, null, (Comment) null);
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema) {
|
||||
this(name, schema, null, null, null, null, (Comment) null);
|
||||
this(name, schema, null, (ForeignKey<?, R>) null, null, null, (Comment) null);
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<R> aliased) {
|
||||
this(name, schema, null, null, aliased, null, (Comment) null);
|
||||
this(name, schema, null, (ForeignKey<?, R>) null, aliased, null, (Comment) null);
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<R> aliased, Field<?>[] parameters) {
|
||||
this(name, schema, null, null, aliased, parameters, (Comment) null);
|
||||
this(name, schema, null, (ForeignKey<?, R>) null, aliased, parameters, (Comment) null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,42 +194,79 @@ implements
|
||||
*/
|
||||
@Deprecated
|
||||
public TableImpl(Name name, Schema schema, Table<R> aliased, Field<?>[] parameters, String comment) {
|
||||
this(name, schema, null, null, aliased, parameters, DSL.comment(comment));
|
||||
this(name, schema, null, (ForeignKey<?, R>) null, aliased, parameters, DSL.comment(comment));
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<R> aliased, Field<?>[] parameters, Comment comment) {
|
||||
this(name, schema, null, null, aliased, parameters, comment);
|
||||
this(name, schema, null, (ForeignKey<?, R>) null, aliased, parameters, comment);
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<R> aliased, Field<?>[] parameters, Comment comment, TableOptions options) {
|
||||
this(name, schema, null, null, aliased, parameters, comment, options);
|
||||
this(name, schema, null, (ForeignKey<?, R>) null, aliased, parameters, comment, options);
|
||||
}
|
||||
|
||||
public TableImpl(Table<?> child, ForeignKey<?, R> path, Table<R> parent) {
|
||||
this(createPathAlias(child, path), null, child, path, parent, null, parent.getCommentPart());
|
||||
}
|
||||
|
||||
public TableImpl(Table<?> parent, InverseForeignKey<?, R> path, Table<R> child) {
|
||||
this(createPathAlias(parent, path), null, parent, path, child, null, child.getCommentPart());
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<?> child, ForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment) {
|
||||
this(name, schema, child, path, aliased, parameters, comment, TableOptions.table());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public TableImpl(Name name, Schema schema, Table<?> parent, InverseForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment) {
|
||||
this(name, schema, parent, path, aliased, parameters, comment, TableOptions.table());
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<?> child, ForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment, TableOptions options) {
|
||||
this(name, schema, child, path, null, null, aliased, parameters, comment, options);
|
||||
}
|
||||
|
||||
public TableImpl(Name name, Schema schema, Table<?> parent, InverseForeignKey<?, R> path, Table<R> aliased, Field<?>[] parameters, Comment comment, TableOptions options) {
|
||||
this(name, schema, null, null, parent, path, aliased, parameters, comment, options);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
private TableImpl(
|
||||
Name name,
|
||||
Schema schema,
|
||||
Table<?> child, ForeignKey<?, R> childPath,
|
||||
Table<?> parent, InverseForeignKey<?, R> parentPath,
|
||||
Table<R> aliased,
|
||||
Field<?>[] parameters,
|
||||
Comment comment,
|
||||
TableOptions options
|
||||
) {
|
||||
super(options, name, schema, comment);
|
||||
|
||||
this.fields = new FieldsImpl<>();
|
||||
|
||||
if (child != null) {
|
||||
this.child = child;
|
||||
this.childPath = path == null ? null : Tools.aliasedKey((ForeignKey) path, child, this);
|
||||
this.childPath = childPath == null ? null : Tools.aliasedKey((ForeignKey) childPath, child, this);
|
||||
this.parent = null;
|
||||
this.parentPath = null;
|
||||
}
|
||||
else if (parent != null) {
|
||||
this.child = null;
|
||||
this.childPath = null;
|
||||
this.parent = parent;
|
||||
this.parentPath = parentPath == null ? null : Tools.aliasedKey((ForeignKey) parentPath.getForeignKey(), this, parent).getInverseKey();
|
||||
}
|
||||
else if (aliased instanceof TableImpl t) {
|
||||
this.child = t.child;
|
||||
this.childPath = t.childPath;
|
||||
this.parent = t.parent;
|
||||
this.parentPath = t.parentPath;
|
||||
}
|
||||
else {
|
||||
this.child = null;
|
||||
this.childPath = null;
|
||||
this.parent = null;
|
||||
this.parentPath = null;
|
||||
}
|
||||
|
||||
if (aliased != null) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user