diff --git a/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java b/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java index 256bef72e0..166b3354bf 100644 --- a/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java +++ b/jOOQ-codegen/src/main/java/org/jooq/codegen/MatcherStrategy.java @@ -51,6 +51,9 @@ import org.jooq.meta.ColumnDefinition; import org.jooq.meta.Definition; import org.jooq.meta.EmbeddableDefinition; import org.jooq.meta.EnumDefinition; +import org.jooq.meta.ForeignKeyDefinition; +import org.jooq.meta.InverseForeignKeyDefinition; +import org.jooq.meta.ManyToManyKeyDefinition; import org.jooq.meta.Patterns; import org.jooq.meta.RoutineDefinition; import org.jooq.meta.SchemaDefinition; @@ -60,7 +63,7 @@ import org.jooq.meta.jaxb.MatcherRule; import org.jooq.meta.jaxb.MatcherTransformType; import org.jooq.meta.jaxb.Matchers; import org.jooq.meta.jaxb.MatchersCatalogType; -import org.jooq.meta.jaxb.MatchersEmbeddableType; +import org.jooq.meta.jaxb.*; import org.jooq.meta.jaxb.MatchersEnumType; import org.jooq.meta.jaxb.MatchersFieldType; import org.jooq.meta.jaxb.MatchersRoutineType; @@ -191,6 +194,27 @@ public class MatcherStrategy extends DefaultGeneratorStrategy { return emptyList(); } + private final List foreignKeys(Definition definition) { + if (definition instanceof ForeignKeyDefinition) + return matchers.getForeignKeys(); + + return emptyList(); + } + + private final List inverseForeignKeys(Definition definition) { + if (definition instanceof InverseForeignKeyDefinition) + return matchers.getForeignKeys(); + + return emptyList(); + } + + private final List manyToManyKeys(Definition definition) { + if (definition instanceof ManyToManyKeyDefinition) + return matchers.getForeignKeys(); + + return emptyList(); + } + private final List fields(Definition definition) { if (definition instanceof ColumnDefinition) return matchers.getFields(); @@ -299,6 +323,27 @@ public class MatcherStrategy extends DefaultGeneratorStrategy { return result; } + for (MatchersForeignKeyType foreignKeys : foreignKeys(definition)) { + String result = match(definition, foreignKeys.getExpression(), foreignKeys.getMethodName()); + + if (result != null) + return result; + } + + for (MatchersForeignKeyType inverseForeignKeys : inverseForeignKeys(definition)) { + String result = match(definition, inverseForeignKeys.getExpression(), inverseForeignKeys.getMethodNameInverse()); + + if (result != null) + return result; + } + + for (MatchersForeignKeyType manyToManyKeys : manyToManyKeys(definition)) { + String result = match(definition, manyToManyKeys.getExpression(), manyToManyKeys.getMethodNameManyToMany()); + + if (result != null) + return result; + } + // Default to standard behaviour return super.getJavaMethodName(definition, mode); } diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Generate.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Generate.java index 460b7476f2..9e81454c5f 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Generate.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Generate.java @@ -38,8 +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 implicitJoinPathsToMany = true; @XmlElement(defaultValue = "true") protected Boolean implicitJoinPathsUseTableNameForUnambiguousFKs = true; @XmlElement(defaultValue = "true") diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Matchers.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Matchers.java index 76488d06bd..8c791b0771 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Matchers.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/Matchers.java @@ -25,6 +25,7 @@ import org.jooq.util.jaxb.tools.XMLBuilder; "catalogs", "schemas", "tables", + "foreignKeys", "fields", "routines", "sequences", @@ -47,6 +48,9 @@ public class Matchers implements Serializable, XMLAppendable @XmlElementWrapper(name = "tables") @XmlElement(name = "table") protected List tables; + @XmlElementWrapper(name = "foreignKeys") + @XmlElement(name = "table") + protected List foreignKeys; @XmlElementWrapper(name = "fields") @XmlElement(name = "field") protected List fields; @@ -96,6 +100,17 @@ public class Matchers implements Serializable, XMLAppendable this.tables = tables; } + public List getForeignKeys() { + if (foreignKeys == null) { + foreignKeys = new ArrayList(); + } + return foreignKeys; + } + + public void setForeignKeys(List foreignKeys) { + this.foreignKeys = foreignKeys; + } + public List getFields() { if (fields == null) { fields = new ArrayList(); @@ -214,6 +229,27 @@ public class Matchers implements Serializable, XMLAppendable return this; } + public Matchers withForeignKeys(MatchersForeignKeyType... values) { + if (values!= null) { + for (MatchersForeignKeyType value: values) { + getForeignKeys().add(value); + } + } + return this; + } + + public Matchers withForeignKeys(Collection values) { + if (values!= null) { + getForeignKeys().addAll(values); + } + return this; + } + + public Matchers withForeignKeys(List foreignKeys) { + setForeignKeys(foreignKeys); + return this; + } + public Matchers withFields(MatchersFieldType... values) { if (values!= null) { for (MatchersFieldType value: values) { @@ -324,6 +360,7 @@ public class Matchers implements Serializable, XMLAppendable builder.append("catalogs", "catalog", catalogs); builder.append("schemas", "schema", schemas); builder.append("tables", "table", tables); + builder.append("foreignKeys", "table", foreignKeys); builder.append("fields", "field", fields); builder.append("routines", "routine", routines); builder.append("sequences", "sequence", sequences); @@ -377,6 +414,15 @@ public class Matchers implements Serializable, XMLAppendable return false; } } + if (foreignKeys == null) { + if (other.foreignKeys!= null) { + return false; + } + } else { + if (!foreignKeys.equals(other.foreignKeys)) { + return false; + } + } if (fields == null) { if (other.fields!= null) { return false; @@ -432,6 +478,7 @@ public class Matchers implements Serializable, XMLAppendable result = ((prime*result)+((catalogs == null)? 0 :catalogs.hashCode())); result = ((prime*result)+((schemas == null)? 0 :schemas.hashCode())); result = ((prime*result)+((tables == null)? 0 :tables.hashCode())); + result = ((prime*result)+((foreignKeys == null)? 0 :foreignKeys.hashCode())); result = ((prime*result)+((fields == null)? 0 :fields.hashCode())); result = ((prime*result)+((routines == null)? 0 :routines.hashCode())); result = ((prime*result)+((sequences == null)? 0 :sequences.hashCode())); diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/MatchersForeignKeyType.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/MatchersForeignKeyType.java new file mode 100644 index 0000000000..50038254c9 --- /dev/null +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/MatchersForeignKeyType.java @@ -0,0 +1,214 @@ + +package org.jooq.meta.jaxb; + +import java.io.Serializable; +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlType; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import org.jooq.util.jaxb.tools.StringAdapter; +import org.jooq.util.jaxb.tools.XMLAppendable; +import org.jooq.util.jaxb.tools.XMLBuilder; + + +/** + * Declarative naming strategy configuration for foreign key names. + * + * + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "MatchersForeignKeyType", propOrder = { + +}) +@SuppressWarnings({ + "all" +}) +public class MatchersForeignKeyType implements Serializable, XMLAppendable +{ + + private final static long serialVersionUID = 31900L; + @XmlJavaTypeAdapter(StringAdapter.class) + protected String expression; + protected MatcherRule methodName; + protected MatcherRule methodNameInverse; + protected MatcherRule methodNameManyToMany; + + /** + * This table matcher applies to all unqualified or qualified table names matched by this expression. If left empty, this matcher applies to all tables. + * + */ + public String getExpression() { + return expression; + } + + /** + * This table matcher applies to all unqualified or qualified table names matched by this expression. If left empty, this matcher applies to all tables. + * + */ + public void setExpression(String value) { + this.expression = value; + } + + /** + * This rule influences the naming of the generated to-one path join methods. + * + */ + public MatcherRule getMethodName() { + return methodName; + } + + /** + * This rule influences the naming of the generated to-one path join methods. + * + */ + public void setMethodName(MatcherRule value) { + this.methodName = value; + } + + /** + * This rule influences the naming of the generated to-many path join methods. + * + */ + public MatcherRule getMethodNameInverse() { + return methodNameInverse; + } + + /** + * This rule influences the naming of the generated to-many path join methods. + * + */ + public void setMethodNameInverse(MatcherRule value) { + this.methodNameInverse = value; + } + + /** + * This rule influences the naming of the generated many-to-many path join methods. + * + */ + public MatcherRule getMethodNameManyToMany() { + return methodNameManyToMany; + } + + /** + * This rule influences the naming of the generated many-to-many path join methods. + * + */ + public void setMethodNameManyToMany(MatcherRule value) { + this.methodNameManyToMany = value; + } + + /** + * This table matcher applies to all unqualified or qualified table names matched by this expression. If left empty, this matcher applies to all tables. + * + */ + public MatchersForeignKeyType withExpression(String value) { + setExpression(value); + return this; + } + + /** + * This rule influences the naming of the generated to-one path join methods. + * + */ + public MatchersForeignKeyType withMethodName(MatcherRule value) { + setMethodName(value); + return this; + } + + /** + * This rule influences the naming of the generated to-many path join methods. + * + */ + public MatchersForeignKeyType withMethodNameInverse(MatcherRule value) { + setMethodNameInverse(value); + return this; + } + + /** + * This rule influences the naming of the generated many-to-many path join methods. + * + */ + public MatchersForeignKeyType withMethodNameManyToMany(MatcherRule value) { + setMethodNameManyToMany(value); + return this; + } + + @Override + public final void appendTo(XMLBuilder builder) { + builder.append("expression", expression); + builder.append("methodName", methodName); + builder.append("methodNameInverse", methodNameInverse); + builder.append("methodNameManyToMany", methodNameManyToMany); + } + + @Override + public String toString() { + XMLBuilder builder = XMLBuilder.nonFormatting(); + appendTo(builder); + return builder.toString(); + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass()!= that.getClass()) { + return false; + } + MatchersForeignKeyType other = ((MatchersForeignKeyType) that); + if (expression == null) { + if (other.expression!= null) { + return false; + } + } else { + if (!expression.equals(other.expression)) { + return false; + } + } + if (methodName == null) { + if (other.methodName!= null) { + return false; + } + } else { + if (!methodName.equals(other.methodName)) { + return false; + } + } + if (methodNameInverse == null) { + if (other.methodNameInverse!= null) { + return false; + } + } else { + if (!methodNameInverse.equals(other.methodNameInverse)) { + return false; + } + } + if (methodNameManyToMany == null) { + if (other.methodNameManyToMany!= null) { + return false; + } + } else { + if (!methodNameManyToMany.equals(other.methodNameManyToMany)) { + return false; + } + } + return true; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = ((prime*result)+((expression == null)? 0 :expression.hashCode())); + result = ((prime*result)+((methodName == null)? 0 :methodName.hashCode())); + result = ((prime*result)+((methodNameInverse == null)? 0 :methodNameInverse.hashCode())); + result = ((prime*result)+((methodNameManyToMany == null)? 0 :methodNameManyToMany.hashCode())); + return result; + } + +} diff --git a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java index 16cb105b5d..0dc36605a4 100644 --- a/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java +++ b/jOOQ-meta/src/main/java/org/jooq/meta/jaxb/ObjectFactory.java @@ -101,6 +101,14 @@ public class ObjectFactory { return new MatchersTableType(); } + /** + * Create an instance of {@link MatchersForeignKeyType } + * + */ + public MatchersForeignKeyType createMatchersForeignKeyType() { + return new MatchersForeignKeyType(); + } + /** * Create an instance of {@link MatchersFieldType } * diff --git a/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.19.0.xsd b/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.19.0.xsd index fe02a72ebc..8c65cddb83 100644 --- a/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.19.0.xsd +++ b/jOOQ-meta/src/main/resources/org/jooq/meta/xsd/jooq-codegen-3.19.0.xsd @@ -179,6 +179,10 @@ + + + + @@ -358,6 +362,33 @@ and follow its (undocumented!) assumptions (e.g. constructors, etc.). Use this a + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1952,7 +1983,7 @@ This is a prerequisite for various advanced features]]> - + EXPERIMENTAL functionality! Do not use this feature, yet]]>