diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorWriter.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorWriter.java index d131be2fe5..5b84c65508 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorWriter.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/GeneratorWriter.java @@ -262,7 +262,12 @@ public abstract class GeneratorWriter> { translated = new ArrayList<>(); } - appendWrapped(String.format(string, translated.toArray()), indent.toString()); + try { + appendWrapped(String.format(string, translated.toArray()), indent.toString()); + } + catch (Exception e) { + throw new RuntimeException("Error when formatting " + string + " with args " + Arrays.asList(args), e); + } } else appendWrapped(string, indent.toString()); diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java index 46c9b0d37e..0b5065f24e 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/JavaGenerator.java @@ -6043,12 +6043,29 @@ public class JavaGenerator extends AbstractGenerator { ? "function" : "table"; final List parameters = table.getParameters(); + final boolean supportsPathsToOne = generateGlobalKeyReferences() + && !table.isTableValuedFunction() + && generateImplicitJoinPathsToOne() + && (generateImplicitJoinPathUnusedConstructors() || !table.getInverseForeignKeys().isEmpty()); + + final boolean supportsPathsToMany = generateGlobalKeyReferences() + && !table.isTableValuedFunction() + && generateImplicitJoinPathsToMany() + && (generateImplicitJoinPathUnusedConstructors() || !table.getForeignKeys().isEmpty()); printPackage(out, table); if (scala) { out.println("object %s {", className); printSingletonInstance(out, table); + + // [#14985] Scala nested classes have to be located in the object + if (generateImplicitJoinPathTableSubtypes() && (supportsPathsToOne || supportsPathsToMany)) { + out.println(); + out.println("%sclass %sPath(path: %s[_ <: %s], childPath: %s[_ <: %s, %s], parentPath: %s[_ <: %s, %s]) extends %s(path, childPath, parentPath) with %s[%s]", + visibility(), className, Table.class, Record.class, ForeignKey.class, Record.class, recordType, InverseForeignKey.class, Record.class, recordType, className, Path.class, recordType); + } + out.println("}"); out.println(); } @@ -6360,76 +6377,37 @@ public class JavaGenerator extends AbstractGenerator { out.println("}"); } - if (generateGlobalKeyReferences() && !table.isTableValuedFunction()) { - boolean supportsPathsToOne = false; - boolean supportsPathsToMany = false; + if (supportsPathsToOne || supportsPathsToMany) { + out.println(); - if (generateImplicitJoinPathsToOne() - && (generateImplicitJoinPathUnusedConstructors() || !table.getInverseForeignKeys().isEmpty()) - ) { - supportsPathsToOne = true; - out.println(); - - if (scala) { - out.println("%sdef this(child: %s[_ <: %s], key: %s[_ <: %s, %s]) = this(%s.createPathAlias(child, key), child, key, null, %s, null)", - visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId); - } - else if (kotlin) { - out.println("%sconstructor(child: %s, key: %s): this(%s.createPathAlias(child, key), child, key, null, %s, null)", - visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, Internal.class, tableId); - } - else { - out.println("%s %s(%s child, %s key) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType); - out.println("super(child, key, %s);", tableId); - out.println("}"); - } + if (scala) { + out.println("%sdef this(path: %s[_ <: %s], childPath: %s[_ <: %s, %s], parentPath: %s[_ <: %s, %s]) = this(%s.createPathAlias(path, childPath, parentPath), path, childPath, parentPath, %s, null)", + visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, InverseForeignKey.class, Record.class, recordType, Internal.class, tableId); + } + else if (kotlin) { + out.println("%sconstructor(path: %s, childPath: %s?, parentPath: %s?): this(%s.createPathAlias(path, childPath, parentPath), path, childPath, parentPath, %s, null)", + visibility(), Table.class, Record.class, ForeignKey.class, Record.class, recordType, InverseForeignKey.class, Record.class, recordType, Internal.class, tableId); + } + else { + out.println("%s %s(%s path, %s childPath, %s parentPath) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType, InverseForeignKey.class, recordType); + out.println("super(path, childPath, parentPath, %s);", tableId); + out.println("}"); } - if (generateImplicitJoinPathsToMany() - && (generateImplicitJoinPathUnusedConstructors() || !table.getForeignKeys().isEmpty()) - ) { - supportsPathsToMany = true; + if (generateImplicitJoinPathTableSubtypes()) { out.println(); - if (scala) { - out.println("%sdef this(parent: %s[_ <: %s], key: %s[_ <: %s, %s]) = this(%s.createPathAlias(parent, key.getForeignKey()), parent, null, key, %s, null)", - visibility(), Table.class, Record.class, InverseForeignKey.class, Record.class, recordType, Internal.class, tableId); - } + // [#14985] Scala nested classes have to be located in the companion object + if (scala) {} else if (kotlin) { - out.println("%sconstructor(parent: %s, key: %s): this(%s.createPathAlias(parent, key.foreignKey), parent, null, key, %s, null)", - visibility(), Table.class, Record.class, InverseForeignKey.class, Record.class, recordType, Internal.class, tableId); + out.println("%sopen class %sPath(path: %s, childPath: %s?, parentPath: %s?) : %s(path, childPath, parentPath), %s<%s>", + visibility(), className, Table.class, Record.class, ForeignKey.class, Record.class, recordType, InverseForeignKey.class, Record.class, recordType, className, Path.class, recordType); } else { - out.println("%s %s(%s parent, %s key) {", visibility(), Record.class, className, Table.class, InverseForeignKey.class, recordType); - out.println("super(parent, key, %s);", tableId); + out.println("%s static class %sPath extends %s implements %s<%s> {", visibility(), className, className, Path.class, recordType); + out.println("%s %sPath(%s path, %s childPath, %s parentPath) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType, InverseForeignKey.class, recordType); + out.println("super(path, childPath, parentPath);"); out.println("}"); - } - } - - if (generateImplicitJoinPathTableSubtypes() && (supportsPathsToOne || supportsPathsToMany)) { - out.println(); - - if (scala) { - // TODO: - } - else if (kotlin) { - // TODO: - } - else { - out.println("public static class %sPath extends %s implements %s<%s> {", className, className, Path.class, recordType); - - if (supportsPathsToOne) { - out.println("%s %sPath(%s child, %s key) {", visibility(), Record.class, className, Table.class, ForeignKey.class, recordType); - out.println("super(child, key);"); - out.println("}"); - } - - if (supportsPathsToMany) { - out.println("%s %sPath(%s parent, %s key) {", visibility(), Record.class, className, Table.class, InverseForeignKey.class, recordType); - out.println("super(parent, key);"); - out.println("}"); - } - out.println("}"); } } @@ -6725,12 +6703,12 @@ public class JavaGenerator extends AbstractGenerator { ); if (scala) { - out.println("%slazy val %s: %s = { new %s(this, %s) }", visibility(), scalaWhitespaceSuffix(keyMethodName), referencedTableClassName, referencedTableClassName, keyFullId); + out.println("%slazy val %s: %s = { new %s(this, %s, null) }", visibility(), scalaWhitespaceSuffix(keyMethodName), referencedTableClassName, referencedTableClassName, keyFullId); } else if (kotlin) { out.println("%sfun %s(): %s {", visibility(), keyMethodName, referencedTableClassName); out.println("if (!this::_%s.isInitialized)", unquotedKeyMethodName); - out.println("_%s = %s(this, %s)", unquotedKeyMethodName, referencedTableClassName, keyFullId); + out.println("_%s = %s(this, %s, null)", unquotedKeyMethodName, referencedTableClassName, keyFullId); out.println(); out.println("return _%s;", unquotedKeyMethodName); out.println("}"); @@ -6744,7 +6722,7 @@ public class JavaGenerator extends AbstractGenerator { else { out.println("%s%s %s() {", visibility(), referencedTableClassName, keyMethodName); out.println("if (_%s == null)", keyMethodName); - out.println("_%s = new %s(this, %s);", keyMethodName, referencedTableClassName, keyFullId); + out.println("_%s = new %s(this, %s, null);", keyMethodName, referencedTableClassName, keyFullId); out.println(); out.println("return _%s;", keyMethodName); out.println("}"); @@ -6802,12 +6780,12 @@ public class JavaGenerator extends AbstractGenerator { ); if (scala) { - out.println("%slazy val %s: %s = { new %s(this, %s.getInverseKey()) }", visibility(), scalaWhitespaceSuffix(keyMethodName), referencingTableClassName, referencingTableClassName, keyFullId); + out.println("%slazy val %s: %s = { new %s(this, null, %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("_%s = %s(this, null, %s.inverseKey)", unquotedKeyMethodName, referencingTableClassName, keyFullId); out.println(); out.println("return _%s;", unquotedKeyMethodName); out.println("}"); @@ -6821,7 +6799,7 @@ public class JavaGenerator extends AbstractGenerator { 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("_%s = new %s(this, null, %s.getInverseKey());", keyMethodName, referencingTableClassName, keyFullId); out.println(); out.println("return _%s;", keyMethodName); out.println("}"); diff --git a/jOOQ/src/main/java/org/jooq/impl/Internal.java b/jOOQ/src/main/java/org/jooq/impl/Internal.java index db6f3b0b4f..8497f34c68 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Internal.java +++ b/jOOQ/src/main/java/org/jooq/impl/Internal.java @@ -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; @@ -291,24 +292,16 @@ public final class Internal { * Factory method for path aliases. */ @NotNull - public static final Name createPathAlias(Table child, ForeignKey path) { - return createPathAlias(child, path, ""); - } + public static final Name createPathAlias(Table path, ForeignKey childPath, InverseForeignKey parentPath) { + Name name = childPath != null + ? DSL.name(childPath.getName()) + : DSL.name(parentPath.getName() + ".inverse"); - /** - * Factory method for path aliases. - */ - @NotNull - static final Name createPathAlias(Table child, ForeignKey path, String suffix) { - Name name = DSL.name(path.getName() + suffix); - - if (child instanceof TableImpl t) { - if (t.childPath != null) - name = createPathAlias(t.path, t.childPath).append(name); - else if (t.parentPath != null) - name = createPathAlias(t.path, t.parentPath.getForeignKey(), ".inverse").append(name); + if (path instanceof TableImpl t) { + if (t.path != null) + name = createPathAlias(t.path, t.childPath, t.parentPath).append(name); else - name = child.getQualifiedName().append(name); + name = path.getQualifiedName().append(name); } return DSL.name("alias_" + hash(name)); diff --git a/jOOQ/src/main/java/org/jooq/impl/TableImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableImpl.java index 48bf78f863..537e69f553 100644 --- a/jOOQ/src/main/java/org/jooq/impl/TableImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/TableImpl.java @@ -175,19 +175,19 @@ implements } public TableImpl(Name name) { - this(name, null, null, (ForeignKey) null, null, null, (Comment) null); + this(name, null, null, null, null, null, null, (Comment) null); } public TableImpl(Name name, Schema schema) { - this(name, schema, null, (ForeignKey) null, null, null, (Comment) null); + this(name, schema, null, null, null, null, null, (Comment) null); } public TableImpl(Name name, Schema schema, Table aliased) { - this(name, schema, null, (ForeignKey) null, aliased, null, (Comment) null); + this(name, schema, null, null, null, aliased, null, (Comment) null); } public TableImpl(Name name, Schema schema, Table aliased, Field[] parameters) { - this(name, schema, null, (ForeignKey) null, aliased, parameters, (Comment) null); + this(name, schema, null, null, null, aliased, parameters, (Comment) null); } /** @@ -206,30 +206,38 @@ implements this(name, schema, null, (ForeignKey) null, aliased, parameters, comment, options); } - public TableImpl(Table child, ForeignKey childPath, Table parent) { - this(createPathAlias(child, childPath), null, child, childPath, parent, null, parent.getCommentPart()); + /** + * @deprecated - [#13639] [#14985] [#15005] - 3.19.0 - Please re-generate your code. + */ + @Deprecated + public TableImpl(Table path, ForeignKey childPath, Table parent) { + this(path, childPath, null, parent); } - public TableImpl(Table parent, InverseForeignKey parentPath, Table child) { - this(createPathAlias(parent, parentPath.getForeignKey(), ".inverse"), null, parent, parentPath, child, null, child.getCommentPart()); + public TableImpl(Table path, ForeignKey childPath, InverseForeignKey parentPath, Table parent) { + this(createPathAlias(path, childPath, parentPath), null, path, childPath, parentPath, parent, null, parent.getCommentPart()); } + /** + * @deprecated - [#13639] [#14985] [#15005] - 3.19.0 - Please re-generate your code. + */ + @Deprecated public TableImpl(Name name, Schema schema, Table path, ForeignKey childPath, Table aliased, Field[] parameters, Comment comment) { this(name, schema, path, childPath, aliased, parameters, comment, TableOptions.table()); } - public TableImpl(Name name, Schema schema, Table path, InverseForeignKey parentPath, Table aliased, Field[] parameters, Comment comment) { - this(name, schema, path, null, parentPath, aliased, parameters, comment, TableOptions.table()); + public TableImpl(Name name, Schema schema, Table path, ForeignKey childPath, InverseForeignKey parentPath, Table aliased, Field[] parameters, Comment comment) { + this(name, schema, path, childPath, parentPath, aliased, parameters, comment, TableOptions.table()); } + /** + * @deprecated - [#13639] [#14985] [#15005] - 3.19.0 - Please re-generate your code. + */ + @Deprecated public TableImpl(Name name, Schema schema, Table path, ForeignKey childPath, Table aliased, Field[] parameters, Comment comment, TableOptions options) { this(name, schema, path, childPath, null, aliased, parameters, comment, options); } - public TableImpl(Name name, Schema schema, Table path, InverseForeignKey parentPath, Table aliased, Field[] parameters, Comment comment, TableOptions options) { - this(name, schema, path, null, parentPath, aliased, parameters, comment, options); - } - @SuppressWarnings({ "rawtypes", "unchecked" }) public TableImpl( Name name,