[jOOQ/jOOQ#14993] Add a new <matchers/> subelement <foreignKeys/>

This commit is contained in:
Lukas Eder 2023-05-01 10:33:06 +02:00
parent b096a11858
commit 47f59ce5d3
6 changed files with 349 additions and 4 deletions

View File

@ -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<MatchersForeignKeyType> foreignKeys(Definition definition) {
if (definition instanceof ForeignKeyDefinition)
return matchers.getForeignKeys();
return emptyList();
}
private final List<MatchersForeignKeyType> inverseForeignKeys(Definition definition) {
if (definition instanceof InverseForeignKeyDefinition)
return matchers.getForeignKeys();
return emptyList();
}
private final List<MatchersForeignKeyType> manyToManyKeys(Definition definition) {
if (definition instanceof ManyToManyKeyDefinition)
return matchers.getForeignKeys();
return emptyList();
}
private final List<MatchersFieldType> 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);
}

View File

@ -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")

View File

@ -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<MatchersTableType> tables;
@XmlElementWrapper(name = "foreignKeys")
@XmlElement(name = "table")
protected List<MatchersForeignKeyType> foreignKeys;
@XmlElementWrapper(name = "fields")
@XmlElement(name = "field")
protected List<MatchersFieldType> fields;
@ -96,6 +100,17 @@ public class Matchers implements Serializable, XMLAppendable
this.tables = tables;
}
public List<MatchersForeignKeyType> getForeignKeys() {
if (foreignKeys == null) {
foreignKeys = new ArrayList<MatchersForeignKeyType>();
}
return foreignKeys;
}
public void setForeignKeys(List<MatchersForeignKeyType> foreignKeys) {
this.foreignKeys = foreignKeys;
}
public List<MatchersFieldType> getFields() {
if (fields == null) {
fields = new ArrayList<MatchersFieldType>();
@ -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<MatchersForeignKeyType> values) {
if (values!= null) {
getForeignKeys().addAll(values);
}
return this;
}
public Matchers withForeignKeys(List<MatchersForeignKeyType> 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()));

View File

@ -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;
}
}

View File

@ -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 }
*

View File

@ -179,6 +179,10 @@
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Declarative naming strategy configuration for table names.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="foreignKeys" type="tns:MatchersForeignKeysType" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Declarative naming strategy configuration for foreign key names.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="fields" type="tns:MatchersFieldsType" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Declarative naming strategy configuration for field names.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
@ -358,6 +362,33 @@ and follow its (undocumented!) assumptions (e.g. constructors, etc.). Use this a
</all>
</complexType>
<complexType name="MatchersForeignKeysType">
<sequence>
<element name="table" type="tns:MatchersForeignKeyType" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="MatchersForeignKeyType">
<annotation><appinfo><jxb:class><jxb:javadoc><![CDATA[Declarative naming strategy configuration for foreign key names.]]></jxb:javadoc></jxb:class></appinfo></annotation>
<all>
<element name="expression" type="string" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This table matcher applies to all unqualified or qualified table names matched by this expression. If left empty, this matcher applies to all tables.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="methodName" type="tns:MatcherRule" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This rule influences the naming of the generated to-one path join methods.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="methodNameInverse" type="tns:MatcherRule" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This rule influences the naming of the generated to-many path join methods.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="methodNameManyToMany" type="tns:MatcherRule" minOccurs="0" maxOccurs="1">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[This rule influences the naming of the generated many-to-many path join methods.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
</all>
</complexType>
<complexType name="MatchersFieldsType">
<sequence>
<element name="field" type="tns:MatchersFieldType" minOccurs="1" maxOccurs="unbounded"/>
@ -1952,7 +1983,7 @@ This is a prerequisite for various advanced features]]></jxb:javadoc></jxb:prope
<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">
<element name="implicitJoinPathsToMany" type="boolean" default="true" 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>